这是一个错误的警告吗?
Is this an incorrect warning?
让我们看看这个我经常看到的代码模式:
struct Foo
{
template <typename T>
T* as1() { /* ... */ }
template <typename T>
T* as2(T*) { /* ... */ }
};
前一种方法是这样使用的:
SomeComplexTypeAndNotAuto * a = foo.as1<SomeComplexTypeAndNotAuto>();
虽然后者使用起来更方便,因为您不需要重复复杂类型:
SomeComplexTypeAndNotAuto * a = foo.as2(a);
但是,大多数编译器会拒绝第二种情况并发出 Wuninitialized 警告:
warning: variable 'a' is uninitialized when used within its own initialization [-Wuninitialized]
很明显变量没有用在初始化中,只有它的类型。有没有办法在不处理每个编译器 pragma 的情况下避免此警告?
编辑:
从我最初的 post 看不清楚,但是当我写 SomeComplexTypeNotAuto
时,我的意思是这样的代码:
auto a = foo.as2(a);
无法解析,因为您 必须 提供一种类型以允许编译器推断它。
我的问题具体到方法 as2()
是一个模板这一事实,因此在类型 T
的特化时必须可见。所以编译器可以看到参数 T*
甚至没有名称,所以它不是来自函数内部的 used/usable。因此,我不明白为什么它会警告 "unused variable" 警告,因为很明显它没有被使用。
It's quite clear the variable is not used in the initialization
相反,很明显变量是用于函数参数的初始化。程序的行为未定义。
Is this an incorrect warning?
不,警告是正确的。
一个简单的解决方法是将参数更改为引用:
T* as2(T*&)
请特别注意不要实际读取引用的值。
从 C+11 开始,您可以使用 auto
代替。
不清楚该变量是否未用于初始化。 as2
.
里面可能发生任何事情
如果未使用该变量,则不要传递它 - 而是使用显式模板实例化。
警告是正确的。
a
在它自己的初始化器中有一个未指定的值,并且将它作为函数参数按值传递需要复制它,这需要从它读取,它具有未定义的行为。
不使用结果值并不重要。
您可以通过阻止复制(使用引用参数)来 "fix" 它,但您最终会得到非常奇怪和不寻常的代码,让您的读者感到困惑。我真的不建议使用这种方法。
只需拼出类型,最好先使其更短且更易读。
按照惯例,我们像这样跳过重复的类型名称:
auto* a = foo.as1<SomeComplexTypeAndNotAuto>();
(例如使用 std::make_shared
和朋友时)
另外,查看访问者模式。
让我们看看这个我经常看到的代码模式:
struct Foo
{
template <typename T>
T* as1() { /* ... */ }
template <typename T>
T* as2(T*) { /* ... */ }
};
前一种方法是这样使用的:
SomeComplexTypeAndNotAuto * a = foo.as1<SomeComplexTypeAndNotAuto>();
虽然后者使用起来更方便,因为您不需要重复复杂类型:
SomeComplexTypeAndNotAuto * a = foo.as2(a);
但是,大多数编译器会拒绝第二种情况并发出 Wuninitialized 警告:
warning: variable 'a' is uninitialized when used within its own initialization [-Wuninitialized]
很明显变量没有用在初始化中,只有它的类型。有没有办法在不处理每个编译器 pragma 的情况下避免此警告?
编辑:
从我最初的 post 看不清楚,但是当我写 SomeComplexTypeNotAuto
时,我的意思是这样的代码:
auto a = foo.as2(a);
无法解析,因为您 必须 提供一种类型以允许编译器推断它。
我的问题具体到方法 as2()
是一个模板这一事实,因此在类型 T
的特化时必须可见。所以编译器可以看到参数 T*
甚至没有名称,所以它不是来自函数内部的 used/usable。因此,我不明白为什么它会警告 "unused variable" 警告,因为很明显它没有被使用。
It's quite clear the variable is not used in the initialization
相反,很明显变量是用于函数参数的初始化。程序的行为未定义。
Is this an incorrect warning?
不,警告是正确的。
一个简单的解决方法是将参数更改为引用:
T* as2(T*&)
请特别注意不要实际读取引用的值。
从 C+11 开始,您可以使用 auto
代替。
不清楚该变量是否未用于初始化。 as2
.
如果未使用该变量,则不要传递它 - 而是使用显式模板实例化。
警告是正确的。
a
在它自己的初始化器中有一个未指定的值,并且将它作为函数参数按值传递需要复制它,这需要从它读取,它具有未定义的行为。
不使用结果值并不重要。
您可以通过阻止复制(使用引用参数)来 "fix" 它,但您最终会得到非常奇怪和不寻常的代码,让您的读者感到困惑。我真的不建议使用这种方法。
只需拼出类型,最好先使其更短且更易读。
按照惯例,我们像这样跳过重复的类型名称:
auto* a = foo.as1<SomeComplexTypeAndNotAuto>();
(例如使用 std::make_shared
和朋友时)
另外,查看访问者模式。