【发布时间】:2018-04-16 16:34:41
【问题描述】:
C++17 有一个新属性,[[nodiscard]]。
假设我有一个Result 结构,它有这个属性:
struct [[nodiscard]] Result {
};
现在,如果我调用返回 Result 的函数,如果我不检查返回的 Result,则会收到警告:
Result someFunction();
int main() {
someFunction(); // warning here, as I don't check someFunction's return value
}
这个程序生成:
警告:忽略用“nodiscard”声明的函数的返回值 属性 [-Wunused-result]
到目前为止,一切都很好。现在假设,我有一个特殊的功能,我仍然想返回Result,但如果省略检查,我不希望生成此警告:
Result someNonCriticalFunction();
int main() {
someNonCriticalFunction(); // I don't want to generate a warning here
}
这是因为,someNonCriticalFunction() 做了一些非关键的事情(例如,像printf 这样的事情——我敢打赌,没有人会一直检查printf 的返回值);大多数情况下,我不在乎它是否失败。但我仍然希望它返回Result,因为在极少数情况下,我确实需要它的Result。
有可能以某种方式做到这一点吗?
我不喜欢的可能解决方案:
- 我不喜欢叫它
(void)someNonCriticalFunction(),因为这个函数被调用了很多次,很别扭 - 围绕
someNonCriticalFunction()创建一个包装器,它调用(void)someNonCriticalFunction():我不想仅仅因为这个而有一个不同命名的函数 - 从结果中删除
[[nodiscard]],并将其添加到每个返回Result的函数中
【问题讨论】:
-
您的要求似乎相互矛盾。你想添加一个警告,这样你就永远不会忽略一个结果,但你想忽略它?
-
如果它是 特殊 情况,那么它应该不会发生太多,并且使用转换为
void是可以接受的(带有说明原因的注释)。如果它确实经常发生,那么它就不再是特殊了,我建议您花一些时间考虑一下您的设计和要求。 -
Rust 通过返回
Result<()>(返回空结构的结果类型)来实现这一点。然后,您只需调用.unwrap()即可忽略该错误。也许你可以在你的Result类中添加一个ignore函数。 -
你已经排除了所有合理的解决方案。
-
此外,它还增加了 maintianability 和 readability 和 discoverability 以使函数 IMO 具有
[[nodiscard]]。它确实让处理“特殊情况”变得非常更容易。