c++ [[nodiscard]]有什么用 c++防止函数返回值被忽略【技巧】

[[nodiscard]]是C++17引入的属性,用于标记返回值不应被忽略的函数,如返回状态、资源或关键标志的函数;忽略时编译器警告,配合-Werror=nodiscard等选项可升级为错误。

[[nodiscard]] 是 C++17 引入的属性,用来告诉编译器:这个函数的返回值**不应该被忽略**。如果调用者没用它的返回值,编译器就会发出警告(甚至报错,取决于编译选项)。

什么时候该加 [[nodiscard]]?

适用于那些**返回重要信息、状态或资源**,而忽略它可能导致逻辑错误、资源泄漏或未定义行为的函数:

  • 返回错误码或状态(如 std::expectedstd::optional、自定义结果类型)
  • 返回新分配的资源(如智能指针工厂函数、临时对象构造器)
  • 返回需要显式检查的标志(如 std::regex_match 的返回值)
  • 返回不可复制/移动的对象,其语义依赖于使用(比如某些 RAII 包装器)

怎么用?写法很简单

直接加在函数声明前或后(推荐放在前面,更清晰):

// 示例:一个可能失败的解析函数

[[nodiscard]] std::optional parse_int(const std::string& s);

// 调用时若忽略返回值,GCC/Clang/MSVC 都会警告

parse_int("123"); // ⚠️ 警告:nodiscard 函数的返回值被忽略

配合编译器选项效果更好

单独加 [[nodiscard]] 只触发警告。想强制要求处理,可配合:

  • GCC/Clang:-Werror=nodiscard 把警告升级为错误
  • MSVC:/wd4834 控制,或用 /WX 启用所有警告为错误

这样能确保 CI 或团队开发中没人绕过检查。

注意几个常见坑

  • 不是所有返回值都适合加——比如 int size() const 这种只读接口,忽略它通常无害,加了反而干扰开发体验
  • 类成员函数也可以加:[[nodiscard]] std::string_view get_name() const;
  • C++20 起支持对枚举和类加 [[nodiscard]],表示“创建该类型对象不应被忽略”(例如防止忘记赋值给变量)
  • 如果确实要忽略,可用 (void)func();[[maybe_unused]] auto x = func(); 显式压制