这是不正确的警告吗?

问题描述 投票:4回答:3

让我们看看我经常看到的这种代码模式:

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]

很明显,变量没有在初始化中使用,只有其类型才使用。有没有一种方法可以避免这种警告,而无需处理每个编译器实用程序的地狱?

编辑:

从我最初的帖子中还不清楚,但是当我写SomeComplexTypeNotAuto时,我的意思是这样的代码:auto a = foo.as2(a);无法解析,因为您have提供了一种允许编译器推断的类型。

我的问题是特定于方法as2()是模板的事实,因此对于类型T,它必须在专门化时可见。因此,编译器可以看到参数T*甚至都没有名称,因此在函数内部无法使用/使用。因此,我不明白为什么它警告“未使用的变量”警告,因为很明显它没有被使用。

c++ templates design-patterns initialization warnings
3个回答
6
投票

很明显,变量未在初始化中使用

相反,很明显,在函数参数的初始化中使用了变量is。该程序的行为是不确定的。

这是不正确的警告吗?

否,警告是正确的。


一个简单的解决方法是将参数更改为引用:

T* as2(T*&)

请特别确保不要实际读取参考值。

自C + 11起,但是您可以改用auto


2
投票

警告正确。

[a]在其自己的初始化程序中具有未指定的值,并且按值将其作为函数参数传递要求复制它,这需要对其进行读取,这具有未定义的行为。

不要紧接着不使用原来的结果值。


您可以通过防止复制(带有按引用参数)来“修复”它,但是最终将得到非常奇怪和不寻常的代码,这会使读者感到困惑。我真的不建议这种方法。

只需拼出类型,理想情况下首先使其更短并且更易读。

通常,我们跳过这样的重复类型名称:

auto* a = foo.as1<SomeComplexTypeAndNotAuto>();

(例如,使用std::make_shared和朋友时]

也请查看访客模式。


1
投票

尚不清楚在初始化期间未使用该变量。 as2内部可能发生任何事情。

如果未使用该变量,则不要传递它-请使用显式模板实例化。

© www.soinside.com 2019 - 2024. All rights reserved.