解决什么问题?
// ❌ 传统方式:约定特殊值代表"没有找到"
size_t find(const std::vector<int>& v, int x) {
for (size_t i = 0; i < v.size(); i++)
if (v[i] == x) return i;
return -1; // ❌ -1 对 size_t 来说是 18446744073709551615!而且如果索引 0 是有效值呢?
}
// ❌ 另一种传统方式:输出参数
bool find(const std::vector<int>& v, int x, size_t& out_index);
// API 调用者必须声明一个变量传进去,很啰嗦
optional 的承诺:用类型系统表达"返回值可能不存在"。
什么时候用?
| 场景 | 不用 optional | 用 optional |
|---|---|---|
| 容器查找 | 返回 -1 或 end() |
返回 optional<iterator> |
| 解析 | 返回 bool + 输出参数 |
返回 optional<T> |
| 从可能为空的配置取值 | 抛异常 | 返回 optional<T> |
| 数据库查询 | 返回 nullptr | 返回 optional<Record> |
std::optional<size_t> find(const std::vector<int>& v, int x) {
for (size_t i = 0; i < v.size(); i++)
if (v[i] == x) return i; // ✅ 没有歧义
return std::nullopt; // ✅ 明确表达"没有"
}
auto result = find(vec, 42);
if (result.has_value()) {
// 进入这里说明 result 一定有效
size_t index = result.value(); // 或者 *result
} else {
std::cout << "not found";
}
性能:optional<T> 不分配堆内存,和 T 占同样大的空间(+一个 bool 标记位,通常利用 padding 字节,不增加 sizeof)。