std::optional用于表示可能无值的状态,通过has_value()或布尔判断检查值是否存在,使用value_or()安全获取值,配合std::nullopt表示空状态,适用于函数返回等场景,提升代码安全性与可读性。

在C++17中,std::optional 是一个用于表示“可能存在或不存在”的值的类模板。它解决了传统C++中如何表达“无值”状态的问题,比如使用特殊值(如-1、nullptr)或额外的布尔标志,这些方式容易出错且不够直观。
基本用法
std::optional 可以包装任何类型,用来表明该变量可能有值,也可能没有(即处于“空状态”)。
包含头文件:
#include常见初始化方式:
立即学习“C++免费学习笔记(深入)”;
- 创建一个空的 optional:std::optional
opt; - 直接赋值有值:opt = 42;
- 构造时带值:std::optional
price{3.14}; - 用 in-place 构造复杂类型:std::optional<:string> name{std::in_place, "Alice"};
检查是否有值:
- if (opt.has_value()) 判断是否包含有效值
- 或直接当作布尔值使用:if (opt)
获取值的方法:
- *opt:解引用获取值(必须确保有值,否则未定义行为)
- opt.value():返回值,若为空会抛出异常
- opt.value_or(default_value):有值则返回,否则返回默认值,最安全常用
函数返回 optional 的场景
当函数可能无法产生有效结果时,返回 std::optional 比返回指针或抛异常更清晰。
std::optionalfor (int x : vec) {
if (x % 2 == 0) return x;
}
return std::nullopt; // 显式表示无值
}
调用示例:
auto result = find_first_even({1, 3, 5, 8, 9});if (result) {
std::cout } else {
std::cout }
与 nullopt 和类型推导配合
std::nullopt 是一个字面量,用来表示 optional 的“空状态”,可用于赋值或比较。
std::optionalif (opt == std::nullopt) { /* 为空 */ }
结合 auto 使用时注意类型推导:
auto opt = std::optional(42); // C++17 起支持类模板参数推导最佳实践建议
- 优先使用 value_or() 避免意外访问空值
- 不要滥用 optional,仅在“可选性”语义明确时使用
- 避免将 optional 用于性能敏感路径,因为它有一定开销(标记位+存储)
- 对于大型对象,考虑是否需要用 std::optional,必要时确保移动语义合理
- 禁止通过指针访问内部值(如 &*opt),除非确定有值
基本上就这些。std::optional 让代码更安全、语义更清晰,是现代C++处理可选值的推荐方式。









