std :: ignore用于忽略未使用的变量

gau*_*waj 35 c++ function principles c++11 c++14

用它std::ignore来忽略未使用的变量是一种好方法吗?

假设我有这样的函数:

void func(int i)
{
   //for some reason, I don't need i anymore but I cannot change signature of function    
   std::ignore = i; 
}
Run Code Online (Sandbox Code Playgroud)

附加信息

这是一个例子,一些答案建议使用匿名变量.但是我如何为其他情况做这件事,比如:

int Thread_UnSafe_func_returnSomething():
void func()
{
   // To make it thread safe
   // Also it is required to call only once
   static int i = Thread_UnSafe_func_returnSomething();

   std::ignore = i;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*nov 41

在这种情况下,只是不要写变量名称:

void func(int /*i*/)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

@ Hayt的答案很好,但是使用的C++版本并不总是可用的.不写变量名是一个旧的约定,告诉编译器你实际上不需要变量.

对于更新的问题,我将在构造函数中使用需要初始化的类的静态实例.我说初始化是因为我可以使用这个函数的唯一原因是初始化一些全局对象.

class SomethingInitializer {
public:
    SomethingInitializer() {
        func_returnSomething();
    }
    ~SomethingInitializer() {
        // Note, that when you initialize something it is a good practice to deinitialize it at the end, and here is a proper place for that.
    }
};

void func() {
    static SomethingInitializer initializer;
}
Run Code Online (Sandbox Code Playgroud)

此解决方案有一个小小的奖励:SomethingInitializer符合RAII标准.因此,当应用程序终止析构函数时,它可以进行取消初始化.

注意,编译器知道类可能在构造函数和析构函数中做一些有用的事情,所以它不会抱怨未使用的变量.

  • 你打了我大约2分钟,所以给你我的upvote而不是留下我的答案.我还要注意,如果相应的头文件仍包含类似`void func(int i);`的内容,那就完全没问题了. (3认同)

Hay*_*ayt 38

std::ignore可以工作,但它的目的是用于元组.所以你需要包含元组头,谁知道为赋值做了哪些操作.这也可能会破坏另一个c ++版本,因为它从未被记录为以这种方式使用.

更好的方法是C++ 17属性 [[maybe_unused]]

void func([[maybe_unused]] int i)
{
}
Run Code Online (Sandbox Code Playgroud)

它将声明放在变量声明中,因此您不必在额外的行/语句中声明它.

同样可以用于本地(和本地静态)变量

...
[[maybe_unused]] static int a = something();
...
Run Code Online (Sandbox Code Playgroud)

还有更多:

出现在类,typedef,变量,非静态数据成员,函数,枚举或枚举器的声明中.如果编译器对未使用的实体发出警告,则对于声明为maybe_unused的任何实体,将禁止该警告.

请参见http://en.cppreference.com/w/cpp/language/attributes

至于有关人员,你声明它们未使用后仍然可以使用变量:

是的,这是可能的,但(至少对于clang)如果您使用maybe_unused声明的变量,您将收到警告.

  • @gsamaras我认为这比Alexey的答案更糟糕,因为这会让你不小心搬起石头砸自己的脚,因为虽然OP的意图是不使用该变量,但这个答案不会调用编译器的帮助来验证该意图。 (2认同)

gsa*_*ras 16

std :: ignore不打算用于此目的:

未指定类型的对象,以便可以为其分配任何值而不起作用.在解压缩std :: tuple时用于std :: tie,作为未使用的参数的占位符.


我建议你不要做你正在想的事情,因为在一个真实的大项目中,它会导致代码更难维护,人们会看到函数的原型,会看到它需要一个参数int i,但实际上功能不需要 - 感觉不好,是吗?:)


Jar*_*d42 8

作为替代方案,无需i从签名中删除(因为某些文档工具可能需要它),有几种方法可以使警告静音:

void func(int i)
{
   static_cast<void>(i); // Silent warning for unused variable
}
Run Code Online (Sandbox Code Playgroud)

它不是完全可移植的,但是大多数编译器都会发出警告.

干净的方法是为此创建一个专用的功能:

template <typename T>
void Unused(T&& /*No name*/) { /*Empty*/ }
Run Code Online (Sandbox Code Playgroud)

然后

void func(int i)
{
   Unused(i); // Silent warning for unused variable
}
Run Code Online (Sandbox Code Playgroud)

  • 你只是在使用它,而没有真正使用它。不错:D (2认同)