贝利信息

c++的[[nodiscard]]属性有什么用? (强制检查返回值)

日期:2026-01-16 00:00 / 作者:冰火之心
不能直接阻止,但能触发编译器警告;它提示返回值有意义、不应被忽略,是否报错取决于编译器及警告设置。

[[nodiscard]] 能阻止调用者忽略返回值吗?

不能直接阻止,但能触发编译器警告(或错误,取决于编译选项)。它只是给编译器一个提示:这个函数/类型/构造函数的返回值“有意义”,不该被丢弃。是否报错,取决于你用的编译器和警告级别设置。

哪些地方可以加 [[nodiscard]]?

支持位置包括:函数声明、枚举定义、类/结构体定义、构造函数(C++20 起)、typedef / alias 声明(C++23)。最常见的是加在函数上。

不加 [[nodiscard]] 会出什么问题?

典型问题是逻辑漏洞难以发现。比如:

std::vector v = {1, 2, 3};
v.push_back(4); // 返回 void,没问题
v.insert(v.begin(), 5); // 返回 iterator,但没人用 —— 暂时无害
auto res = std::binary_search(v.begin(), v.end(), 7); // 返回 bool,但写成 std::binary_search(...);就丢了结果

更危险的是:

怎么让 [[nodiscard]] 真正起作用?

必须配合编译器警告开关:

注意:如果函数返回 void[[nodiscard]] 会被忽略;如果返回值是字面量(如 42)或临时对象且没绑定到引用,某些编译器也可能不警告。

最容易被忽略的是:它不检查“语义上是否该用”,只检查“语法上是否写了”。比如 (void)foo();foo(); 在有重载且某重载返回 void 时,也可能绕过检查。别把它当成银弹,而是配合代码审查和单元测试一起用。