当函数返回值必须使用时应加[[nodiscard]],如错误码、资源、转换对象等;须置于返回类型前,const成员函数中需在const前;c++17支持带提示字符串的变体。
![c++ [[nodiscard]]怎么标记不能忽略返回值的函数](https://img.php.cn/upload/article/001/221/864/179245058522526.png?x-oss-process=image/resize,p_40)
什么时候该用 [[nodiscard]]
当你写的函数返回一个必须被使用的结果时,比如错误码、新分配的资源、转换后的对象,或者任何“调用后不处理返回值就大概率出错”的场景,就该加 [[nodiscard]]。典型例子:std::unique_ptr<t> clone()</t>、std::expected<int err> parse()</int>、bool try_lock()。它不是装饰,是编译器能帮你拦住漏处理返回值的第一道防线。
[[nodiscard]] 的写法和位置
必须紧挨着函数声明(或定义)的返回类型之前,不能放在参数列表后,也不能套在函数体内。成员函数、自由函数、模板函数都支持。
[[nodiscard]] int find_value(); // ✅ 正确:返回类型前 [[nodiscard]] std::string to_upper(const char* s); // ✅ auto process() -> [[nodiscard]] std::optional<int>; // ✅ C++14 后置返回类型写法 void foo() [[nodiscard]]; // ❌ 错误:放错位置,且 void 不该加 </int>
注意:[[nodiscard]] 对 void 函数无效,编译器会忽略或报错;对构造函数、析构函数、重载运算符(如 operator+)也无意义——它们本来就不该被“忽略返回值”地调用。
带提示信息的 [[nodiscard("reason")]]
C++17 起支持带字符串字面量的变体,能让警告更具体,帮助调用方快速理解为什么不能忽略:
[[nodiscard("ownership transferred")]] std::unique_ptr<t> create();</t>[[nodiscard("check result before proceeding")]] bool validate();
不同编译器提示格式略有差异:g++ 和 clang++ 会在警告里显示该字符串;MSVC 从 19.26 开始支持,但需开启 /std:c++17 及以上。不加字符串也能起作用,但加了更容易定位问题根源。
常见误用和坑
容易踩的几个点:
- 忘记给
const成员函数加:如果[[nodiscard]]函数是const的,属性必须写在const前(即返回类型之后、const之前),否则语法错误 - 模板实例化后丢失属性:显式特化或别名模板可能不继承
[[nodiscard]],要手动补上 - 第三方库没加,你调用它时不会警告:这个属性只对加了它的函数生效,不能“传染”到调用链上游
- 宏包装函数时容易丢掉属性:比如
MY_API [[nodiscard]] int func();,若MY_API展开含换行或空格,可能破坏语法
最常被忽略的是 const 成员函数的书写顺序——写成 int get() const [[nodiscard]] 是错的,必须是 [[nodiscard]] int get() const。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











