一、explicit——防止隐式转换
struct StringWrapper {
/* explicit */ StringWrapper(const char* s) { ... }
};
void process(StringWrapper sw);
// 如果没有 explicit:
process("hello"); // 隐式构造 StringWrapper → 可能不是你想要的!
// 如果有 explicit:
process("hello"); // ❌ 编译错误,必须显式构造
process(StringWrapper("hello")); // ✅
规则:所有单参数构造函数都应该加 explicit,除非你真的想让隐式转换发生(极少见)。
二、[[nodiscard]]——返回值不要被忽略
struct Error { int code; };
class Config {
public:
[[nodiscard]] Error load(const std::string& path) {
// 如果加载失败,返回错误
return Error{42};
}
};
Config cfg;
cfg.load("config.ini"); // ⚠️ 编译器警告:返回值被忽略!
// 必须处理:
Error e = cfg.load("config.ini"); // ✅
哪些返回值应该加 [[nodiscard]]?
- 错误码 / 错误对象
unique_ptr/ 智能指针bool类型的"操作是否成功"的返回值- 分配了新资源的返回值