如果一个函数声明了[[nodiscard]],则该函数的返回值不能没有承接,如果没有承接,就会编译报warning

[[nodiscard]]是c++17新特性,但本地用c++11标准编译也能编译过,尚不清楚原因,c++20加入了warning后的额外文字描述功能

测试代码

struct [[nodiscard]] error_info { /*...*/ };
error_info enable_missile_safety_mode() { /*...*/ return {}; }
void launch_missiles() { /*...*/ }
void test_missiles()
{
    enable_missile_safety_mode(); // compiler may warn on discarding a nodiscard value
    launch_missiles();
}
error_info& foo() { static error_info e; /*...*/ return e; }
void f1() { foo(); } // nodiscard type is not returned by value, no warning
// nodiscard( string-literal ) (since C++20):
[[nodiscard("PURE FUN")]] int strategic_value(int x, int y) { return x ^ y; }

int main()
{
    strategic_value(4, 2); // compiler may warn on discarding a nodiscard value
    auto z = strategic_value(0, 0); // ok: return value is not discarded
    return z;
}

一个疑问:
为什么nodiscard属性不是默认值,似乎返回值没有被利用就是一个bug才对

解答:
因为考虑向后兼容,如果改为默认的话,那之前编写的代码将会发出警告,虽然可以编译成功,但这将是个重大的语义变化,新语言使用这个特性作为默认是有道理的,因为不用考虑兼容问题,如Nim语言

nodiscard使用场景:

  • 如果一个函数除了返回某个结果之外没有其他作用,即是纯的。如果不使用结果,则调用肯定是无用的
  • 如果一个返回值必须被检查,比如返回错误码

nodiscard函数在.cc文件定义时可以不写[[nodiscard]]

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐