Std::ignore用于忽略未使用的变量
std::ignore for ignoring unused variable
使用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;
}
<<p> 附加信息/strong> 这是一个例子,一些答案建议使用匿名变量。但是对于其他情况,我该怎么做呢,比如:
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;
}
std::ignore
可以工作,但它打算用于元组。因此,您需要包含元组头文件,谁知道为赋值执行了什么操作。这在另一个c++版本中也可能会被破坏,因为文档中从来没有这样使用过。
[[maybe_unused]]
void func([[maybe_unused]] int i)
{
}
它将声明放在变量声明处,因此您不必在额外的行/语句中声明它。
同样可以用于本地(和本地-静态)变量
...
[[maybe_unused]] static int a = something();
...
还有更多:
出现在类、类型定义、变量、a的声明中非静态数据成员、函数、枚举或枚举数。如果编译器对未使用的实体发出警告,该警告是禁止任何声明为maybe_unused的实体
见http://en.cppreference.com/w/cpp/language/attributes
对于那些在声明变量未使用后仍然可以使用它们的人:
是的,这是可能的,但(至少与clang)你会得到警告,如果你使用maybe_unused
声明的变量。
void func(int /*i*/)
{
...
}
@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;
}
这个解决方案有一个小好处:SomethingInitializer是RAII兼容的。因此,当应用程序终止时,调用析构函数,它可以取消初始化。
注意,编译器知道类可以在构造函数和析构函数中做一些有用的事情,所以它不会抱怨未使用的变量。
std::ignore不是用于此目的:
未指定类型的对象,任何值都可以赋给它而不产生任何影响。用于在解包std::元组时与std::tie一起使用,作为未使用参数的占位符。
我建议你不要做你想做的事,因为在现实世界的大项目中,它会导致更难维护的代码,在那里人们会看到函数的原型,会看到它需要一个参数int i
,但函数在现实中不需要它-感觉不舒服,不是吗?:)
在c++ 17中,可以使用属性[[maybe_unused]]
:
void func([[maybe_unused]]int i)
{
// ...
}
以前,作为替代方案,不需要从签名中删除i
(因为某些文档工具可能需要它),有几种方法可以沉默警告:
cast to
void
:void func(int i) { static_cast<void>(i); // Silence warning for unused variable }
它不是完全可移植的,但这在大多数编译器上抑制了警告。
"clean"方法是创建一个专门的函数:
template <typename T> void Unused(T&& /*No name*/) { /*Empty*/ }
和
void func(int i) { Unused(i); // Silence warning for unused variable }
我想你这里有XY问题。你并不关心如何忽略静态变量;您只希望以线程安全的、可重入的方式调用函数一次(且仅一次)。
我说:你听说过std::call_once
吗?你应该把你的方法重写为
#include <mutex>
int Thread_UnSafe_func_returnSomething();
void func(void)
{
//To make it thread safe
static std::once_flag initComplete;
std::call_once(initComplete, func_returnSomething);
}
另一种方法是使用尾随返回类型,如下所示:
auto func(int i) -> decltype(void(i)) {}
int main() {}
如果你有多个变量,你可以列出它们:
auto func(int i, int j) -> decltype(void(i), void(j)) {}
int main() {}
如果void
不是你想要的,你仍然可以声明你的首选返回类型:
auto func(int i) -> decltype(void(i), int{}) { return 42; }
int main() {}
这个解决方案的优点是:
变量名被保留:正如其他人所提到的,不要给不能作为选项的变量命名(例如,因为你的文档系统)。
你不会用无用的表达式来污染你的函数体,这些表达式旨在沉默一些警告。
你不需要明确定义支持函数来做这些
int f() {
static int i = 0;
static int j = 0;
return void(i), void(j), 42;
}
int main () {}
我想为那些用ARM编译的人提供一个替代方案。
您可以使用_属性_关键字来分配"未使用"属性设置为变量。这样做将导致编译器在变量未被引用时不生成任何警告。
您可以分配"未使用的";属性设置为方法声明中的方法参数。只需将属性关键字紧接在变量名后面,并加上"未使用";属性。我在下面提供了一个例子。
的例子:
void someFunc(int x __attribute__((unused)) );
文档可以在这里引用
- 使用typeid警告未使用的变量
- 未使用的C++未优化的静态成员函数/变量
- C++未使用的变量警告,即使我在函数结束时返回它
- 如何使 Visual Studio 2010 警告未使用的变量
- C 20合同和未使用的变量
- 提升::序列化警告未使用的变量file_version
- 未使用的变量禁止打印?
- GCC和Clang不警告未使用的异常变量
- 避免在 openmp 并行块中使用预编译器语句出现未使用的变量警告
- 抑制警告:未使用的变量
- 错误:非静态数据成员的使用无效,在此范围内未声明变量
- 如何使用非平凡析构函数防止未使用的变量警告
- 为什么这个未使用的变量没有优化掉?
- 为什么msvc编译器在显式调用析构函数时会发出未使用的变量
- 警告:变量已设置,但未使用
- 检测函数范围之外的未使用变量
- 如何禁止显示有关C++中未使用变量的警告
- C++未使用变量的异常
- 为什么在c++函数中使用void(未使用)(和类似的)而不是没有名称的参数来消除未使用变量的警告
- 如何在Eclipse中禁用未使用变量警告?