说我有
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
foo ();
}
Run Code Online (Sandbox Code Playgroud)
然后
error: ignoring return value of ‘int foo()’, declared with attribute nodiscard [-Werror=unused-result]
Run Code Online (Sandbox Code Playgroud)
但如果
int x = foo ();
Run Code Online (Sandbox Code Playgroud)
然后
error: unused variable ‘x’ [-Werror=unused-variable]
Run Code Online (Sandbox Code Playgroud)
是否有一种干净的方式告诉编译器"我想丢弃这个[[nodiscard]]值"?
Ale*_*iev 26
CppCoreGuidelines建议使用std::ignore:
切勿强制转换
(void)为忽略[[nodiscard]]返回值。如果您故意想要丢弃这样的结果,请首先认真考虑这是否真的是一个好主意(函数或返回类型的作者通常有一个很好的理由[[nodiscard]])。如果您仍然认为它是合适的并且您的代码审查者同意,请使用std::ignore =来关闭警告,这是简单、可移植且易于 grep 的。
这与另一个答案中的建议几乎相同boost::ignore_unused,但开箱即用std::。
然而,使用也有缺点std::ignore:
std::ignore是为了其他目的std::ignore甚至不能保证抑制警告Sha*_*our 14
该WG14 nodiscard提案讨论了允许诊断通过铸造作废沉默的理由.它表示强制转换为无效是鼓励(如果不是规范的)沉默它的方式,它遵循现有的实现方式__attribute__((warn_unused_result)):
[[nodiscard]]属性具有广泛的实际用途,由Clang和GCC实现为__attribute __((warn_unused_result)),但是由WG21以[[nodiscard]]的名称标准化.该提议选择了标识符nodiscard,因为偏离此名称会产生与C++的不必要的不兼容性.
该属性的语义在很大程度上依赖于使用的概念,其定义留给实现自由裁量权.但是,WG21指定的非规范性指南是鼓励实现在潜在评估的丢弃值表达式中使用nodiscard函数调用时发出警告诊断,除非它是显式转换为void.这意味着不鼓励实现执行数据流分析(如初始化但未使用的局部变量诊断需要)....
C++的方式是static_cast<void>.
参见草案C++标准[[ dcl.attr.nodiscard] p2:
[注意:nodiscard调用是一个函数调用表达式,它调用先前声明为nodiscard的函数,或者其返回类型是可能是cv限定的类或标记为nodiscard的枚举类型.除非明确转换为void,否则不鼓励将nodiscard调用作为潜在评估的丢弃值表达式的外观. 在这种情况下,实施应该发出警告.这通常是因为丢弃nodiscard呼叫的返回值具有令人惊讶的后果. - 结束说明]
这是一个注释,因此非规范,但基本上这就是现有实现的功能__attribute__((warn_unused_result)).另外,请注意,nodiscard的诊断也是非规范性的,因此对违反nodiscard的诊断并不是错误的,但实施的质量就像通过强制转换为无效一样.
看到关于nodiscard的clang文档,warn_unused_result:
Clang支持在可疑情况下丢弃函数调用表达式的结果时进行诊断的能力.当函数或其返回类型标有[[nodiscard]](或__attribute __((warn_unused_result)))时,会生成诊断,并且函数调用显示为未明确强制转换为void的潜在评估的丢弃值表达式.
Som*_*ken 13
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
static_cast<void>(foo());
}
Run Code Online (Sandbox Code Playgroud)
这基本上告诉编译器" 是的,我知道我放弃了这个,是的,我很确定. "
您还可以int使用其他标记标记返回的内容:
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
[[maybe_unused]] int i = foo ();
}
Run Code Online (Sandbox Code Playgroud)
如果您有一些需要该值的仅调试代码,则可能很有用.
小智 7
我使用(空)辅助函数“丢弃”
template<typename T>
void discard(const T&) {}
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
discard(foo());
}
Run Code Online (Sandbox Code Playgroud)
故意丢弃 [[nodiscard]] 值。
| 归档时间: |
|
| 查看次数: |
2254 次 |
| 最近记录: |