<p>结论:必须先调用 has_value() 再访问 value()、* 或 ->,否则抛 std::bad_optional_access 异常;has_value() 语义明确安全,operator bool 易混淆;value_or(default) 是最安全的取值方式。</p>

直接说结论:不要在没检查的情况下调用 value(),has_value() 是最安全、最明确的检查方式;而 operator bool 虽然简洁,但语义稍弱,容易掩盖意图。
什么时候必须先调用 has_value()?
只要你要用 value()、* 或 -> 访问内部值,就必须确保对象非空。否则会抛出 std::bad_optional_access 异常(调试模式下可能直接崩溃)。
- 函数返回
std::optional<int>,你直接写result.value()—— 危险 - 从容器查找(如
map::find包装成optional)后未判断就解引用 —— 危险 - 把
optional传给需要非空T&的函数前没验证 —— 编译可能过,运行必崩
has_value() vs operator bool:选哪个?
has_value() 明确表达“我关心这个 optional 是否含有效值”,可读性高、无歧义;operator bool 是隐式转换,语法更短,但容易被误读为“是否为真值”(比如和 if (ptr) 混淆)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 推荐在逻辑分支明显、强调“存在性”的地方用
has_value(),例如:if (opt.has_value()) { ... } - 在链式调用或紧凑表达中可用
if (opt),但团队需统一风格,避免混用 - 注意:两者行为完全一致,性能无差别,纯属语义与可维护性选择
value() 的替代方案:为什么优先用 value_or()?
value_or(default) 是最常用、最安全的取值方式,它把“检查 + 取值 + 默认回退”三步合一,且不抛异常。
立即学习“C++免费学习笔记(深入)”;
- 适合有合理默认值的场景,例如配置读取:
config.get_timeout().value_or(3000) - 避免重复判断:
if (opt.has_value()) use(opt.value()); else use(default);→ 直接use(opt.value_or(default)) - 注意:
default会被求值,即使opt有值;若默认值构造开销大,考虑用 lambda 延迟计算(需自行封装)
容易忽略的边界点:nullopt、默认构造与移动语义
std::nullopt 是显式空状态标记,不是值,不能取地址、不能比较大小;默认构造的 optional 和 = std::nullopt 效果相同,但后者语义更清晰。
- 移动后原
optional变为空(has_value() == false),这点和unique_ptr类似,但很多人会忽略 - 对自定义类型 T 使用
optional时,T 的移动/拷贝构造函数是否 noexcept 会影响optional的异常安全性 -
reset()可主动清空,但多数情况不如直接赋std::nullopt直观

















