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()
周围创建一个 Package 器,该 Package 器调用(void)someNonCriticalFunction()
:我不想因为这个函数而使用不同的名称 - 从Result中删除
[[nodiscard]]
,并将其添加到每个返回Result
的函数中
5条答案
按热度按时间r3i60tvu1#
为什么不使用
<tuple>
头文件中的std::ignore
-这将使丢弃显式化:std::ignore
的CPP参考:https://en.cppreference.com/w/cpp/utility/tuple/ignoremi7gmzs62#
他们说,计算机科学中的每一个问题都可以通过增加一层间接性来解决:
这实际上使
Result
有条件地成为[[nodiscard]]
,这允许:尽管实际上,这与以下内容相同:
[[nodiscard]]
,并将其添加到每个返回Result的函数中这让我投了第开始票。
2lpgd9683#
我推荐你排除的选择:
从
Result
中删除[[nodiscard]]
,并将其添加到每个返回结果的函数。但是,既然您看起来并不满意,这里有另一个解决方案,使用bog标准继承:
对于可以丢弃结果的函数,使用
DiscardableResult
作为返回类型:t1rydlwq4#
将结果强制转换为(void *)。
这样就“使用”了编译器的结果,当你使用一个已经使用了nodecdiscard的库,并且你真的不想知道结果时,这是很好的方法。
5rgfhyps5#
您可以使用另一个C++17属性来隐藏警告:可能未使用
通过这种方式,您还可以避免
std::ignore
附带的对std::tuple
的混乱依赖,甚至CppCoreGuidelines也公开推荐使用std::ignore
来忽略[[nodiscard]]
值:不要强制转换为(void)来忽略nodecard返回值。如果你有意要丢弃这样的结果,首先要仔细考虑这是否是个好主意(通常函数或返回类型的作者一开始使用nodecard是有充分理由的)。如果你仍然认为这是合适的,并且你的代码评审员也同意,可以使用std::ignore =关闭警告,这是简单的,可移植的,并且易于grep。
查看C++参考,正式的std::ignore仅指定在
std::tie
中解包元组时使用。虽然std::tie之外的std::ignore的行为没有被正式指定,但是一些代码指南建议使用std::ignore来避免nodecard函数未使用的返回值发出警告。