在特殊情况下是否可以忽略[[nodiscard]]?

时间:2017-11-03 21:00:03

标签: c++ c++17

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():我不希望因为这个而有一个不同的命名函数
  • 从Result中删除[[nodiscard]],并将其添加到每个返回Result
  • 的函数中

3 个答案:

答案 0 :(得分:5)

他们说计算机科学中的每个问题都可以通过添加另一层间接来解决:

template <bool nodiscard=true>
struct Result;

template <>
struct Result<false> {
    // the actual implementation
};

template <>
struct [[nodiscard]] Result<true>
    : Result<false>
{
    using Result<false>::Result;
};

这有效地使Result有条件[[nodiscard]],这允许:

Result<true> someFunction();
Result<false> someNonCriticalFunction();

int main() {
    someFunction();            // warning here
    someNonCriticalFunction(); // no warning here
}

尽管如此,这与:

相同
  
      
  • 从Result中删除[[nodiscard]],并将其添加到每个返回Result
  • 的函数中   

开始我的投票。

答案 1 :(得分:3)

我建议您排除选项:

&#34;从[[nodiscard]]删除Result,并将其添加到每个返回结果的函数中。&#34;

但是既然你似乎对它不满意,那么这是另一个使用沼泽标准继承的解决方案:

struct [[nodiscard]] Result {
};

struct DiscardableResult: public Result {
};

对于可以放弃结果的函数,请使用DiscardableResult作为返回类型:

Result func1();
DiscardableResult func2();

func1(); // will warn
func2(); // will not warn

答案 2 :(得分:0)

将结果转换为 (void *)。

int main()
{
    (void *)someFunction(); //Warning will be gone.
}

就编译器而言,通过这种方式您“使用”了您的结果。非常适合当您使用使用了 nodiscard 的库并且您真的不关心结果时。