std::optional 是 C++17 引入的用于明确表达“可能有值也可能无值”的工具,适用于函数本应返回对象但某些条件下无法构造有效结果的场景,如 map 查找失败、字符串解析非法、配置未设置等;它替代哨兵值和裸指针,不替代异常或 bool+输出参数;需注意类型限制(不可为引用/数组/void)、内存开销及避免嵌套。

std::optional 是 C++17 引入的标准库工具,用于明确表达“可能有值,也可能没有值”的语义,替代裸指针、特殊哨兵值(如 -1、nullptr)或自定义包装类来表示可选返回值。
什么时候该用 std::optional?
适用于函数**本应返回一个对象,但某些条件下无法构造有效结果**的场景。典型例子:
- 从 map 查找键:找不到时不应返回默认构造值(可能不合法),也不该抛异常(查找失败是常见情况)
- 解析字符串为数字:输入非法时无有效 int 可返回
- 异步操作未就绪、配置项未设置、缓存未命中等“暂时不可用”状态
它不是用来替代 bool 返回 + 输出参数,也不是替代异常处理(错误/异常仍该用 exception)。
基本用法:创建、检查、取值
声明一个可能为空的 int:
立即学习“C++免费学习笔记(深入)”;
std::optional
std::optional
std::optional
检查并安全访问:
- if (maybe_x.has_value()) 或简写 if (maybe_x)
- *maybe_x —— 解引用获取值(运行时断言有值,否则未定义行为)
- maybe_x.value() —— 同上,但可自定义异常(重载 value_or() 更推荐)
- maybe_x.value_or(-1) —— 有值则返回值,否则返回默认值 -1(类型需可隐式转换)
作为函数返回值的典型写法
例如安全查找 map 中的值:
std::optional<:string> find_name(const std::map
auto it = db.find(id);
if (it != db.end()) return it->second; // 自动转换为 optional
return std::nullopt; // 或直接 return {};
}
调用方清晰表达意图:
auto name = find_name(db, 123);
if (name) {
std::cout
} else {
std::cout
}
注意边界与限制
- 不能存放引用、数组、void 类型;T 必须满足可移动(且若要原地构造,还需可复制或可移动)
- 不支持空状态的多态(即不能像 variant 那样存多种类型)
- optional
的大小 ≈ sizeof(T) + 1 字节(用于标记状态),对性能敏感场景需留意 - 避免链式 optional(如 optional
>),语义混乱,应扁平化设计
std::optional 让“有没有值”成为类型系统的一部分,调用方无法忽略缺失情况,显著提升接口健壮性与可读性。











