C++属性应置于头文件、实现文件还是两者皆需?
关于C++ [[nodiscard]]属性的放置位置问题
咱们直接说结论:只需要在头文件的函数声明中添加[[nodiscard]]就足够了,实现文件的定义里加不加都不会影响编译器的检查逻辑,通常完全没必要多此一举。
为什么这么说?咱们得搞清楚[[nodiscard]]的作用逻辑:它是用来约束函数的调用者,提醒对方不要忽略返回值。而调用者在使用函数时,只能看到头文件里的声明——编译器在检查调用代码是否忽略返回值时,参考的是声明中的属性,和实现文件里的定义无关。
举个最规范的写法:
// file.h [[nodiscard]] std::future<int> get_data();
// file.cpp std::future<int> get_data() { return std::async([]{ return 42; }); }
这种情况下,任何调用get_data()却不处理返回值的代码,都会被编译器触发警告,完全达到了[[nodiscard]]的目的。
那如果我在实现文件里也加上[[nodiscard]]行不行?当然可以,编译器不会报错,但这属于冗余代码——因为定义里的这个属性对调用者没有任何影响,编译器处理定义时也不会因为这个属性产生额外的行为。
唯一的例外是:如果你的函数没有头文件声明,只有实现文件里的定义(比如静态函数,或者只在当前cpp文件里使用的函数),那这时候你需要在定义上添加[[nodiscard]],因为这时候定义本身就是其他代码调用它的唯一接口依据。
总结一下:
- 对外暴露的函数(有头文件声明):只在头文件的声明加[[nodiscard]]
- 仅在cpp内部使用的函数:在定义上加[[nodiscard]]
内容的提问来源于stack exchange,提问作者Michael Smith
相关产品推荐
相关产品推荐

