操作员的[[nodiscard]]
属性是必需的吗?或者假设编译器会像对大多数可疑丢弃的东西一样发出警告是否安全?
例如重载operator+
,应该应用该属性吗?诸如函数转换运算符或新运算符之类的特殊运算符呢?什么时候学究气?
让我引用 N.Josuttis 的以下论文:“[[nodiscard]]
在图书馆中”(有一些遗漏,请参阅全文):
C++17 引入了该
[[nodiscard]]
属性。问题是,现在在标准库中的何处应用它。应在以下位置添加:
- 不使用返回值总是一个“巨大的错误”(例如总是导致资源泄漏),
- 不使用返回值是麻烦的根源,而且很容易发生(不明显有问题)。
在以下情况下不应添加:
- 至少对于某些输入,不使用返回值是一种可能/常见的编程方式,
- 不使用返回值是没有意义的,但不会造成伤害,通常也不是错误。
因此,
[[nodiscard]]
如果出现这种情况,则不应发出错误代码
- 不使用返回值可能很有用,
- 不使用返回值是常见的,
- 没有伤害,可能没有状态变化意味着不会发生。
永远不需要添加[[nodiscard]]
属性。从cppreference:
如果一个声明为 nodiscard 的函数或返回枚举的函数或按值声明为 nodiscard 的类从一个废弃值表达式调用而不是强制转换为 void,则鼓励编译器发出警告。
注意最后一部分:“......鼓励编译器发出警告。” 就标准而言,不能保证实际上会有警告。它是一个实施质量问题。如果您的编译器确实发出了警告(阅读文档)并且您将此类警告视为错误,那么[[nodiscard]]
很有用。
在丢弃返回只是潜在错误的操作符上使用该属性是迂腐的。我只会在调用运算符时使用它并且丢弃结果总是一个逻辑错误。许多运算符仅使用返回值来启用链接,并且[[nodiscard]]
宁愿对这些运算符感到烦恼。在某些情况下,决定并不那么明显,您选择什么是意见和风格的问题。
运营商是否需要nodiscard?
不,nodiscard 和其他属性是可选的。
或者假设编译器会像对大多数可疑丢弃的东西一样发出警告是否安全?
除非程序格式不正确,否则无法保证语言中的任何警告。
我也不会假设没有 nodiscard 的警告,因为在很多情况下操作结果被故意丢弃。一个常见的例子:
a = b; // result of assignment was discarded
事实上,如果所有丢弃的结果都导致警告,那么 nodiscard 属性就没有任何用途。