跳到主要内容
版本:Next

optional

std::optional 是 C++17 引入的模板类,表示"可能有值,也可能为空"的语义。它是函数返回"可能失败"结果时最干净的表述方式,替代了用哨兵值(如 -1nullptr)或返回 pair<bool, T> 的做法。

头文件与基本特征

#include <optional>
特征说明
作用安全表示"可能有值"的语义
为空时has_value() 返回 false
访问值value()* / ->,为空时 value() 抛异常
默认值value_or(default) 为空时返回默认值
不是指针值语义,可拷贝、移动,无动态内存分配

基本用法

#include <iostream>
#include <optional>
#include <string>

std::optional<int> parse(const std::string& s) {
if (s.empty()) {
return std::nullopt; // 空 optional
}
return std::stoi(s); // 有值
}

int main() {
std::optional<int> r1 = parse("42");
std::optional<int> r2 = parse("");

if (r1.has_value()) {
std::cout << "r1 = " << r1.value() << '\n'; // 42
}

std::cout << "r2 default = " << r2.value_or(-1) << '\n'; // -1

return 0;
}

常用接口

接口作用
has_value()是否有值
value()获取值,为空抛 std::bad_optional_access
operator* / operator->访问内部值(不检查)
value_or(default)有值则返回,否则返回默认值
reset()清空
emplace(args...)原地构造
std::nullopt表示空 optional

典型场景

  1. 函数返回"可能找不到"的结果(替代 pair<bool, T> 或指针)。
  2. 配置项中的可选字段。
  3. 缓存的"已计算/未计算"状态。
std::optional<std::string> findUser(int id) {
if (id <= 0) return std::nullopt;
return "user_" + std::to_string(id);
}

使用注意

  1. *-> 在空时不抛异常,是未定义行为——优先 has_value()value()
  2. optional 的值本身存储在栈上(或容器内),不需要堆分配。
  3. 不要用 optional<T&>(C++17 不支持引用 optional)。

小结

std::optional 让"可能为空"成为类型系统的一部分。用它替代哨兵值和输出参数后,接口意图更明确,调用侧的逻辑也更清晰。