文档目录

解决什么问题?

// ❌ 传统方式:约定特殊值代表"没有找到"
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)。