Skip to content

std::expected(C++23)

一句话

要么持有期望的正常值 T,要么持有意外错误 E——类型安全、零开销的错误传播机制,替代异常和 std::pair<T, Error> 模式。

头文件

#include <expected>

核心 API 速查

操作签名说明
构造(成功值)expected(T value)包装正常值
构造(错误)expected(unexpect_t, E err)包装错误(std::unexpected{err}
检查是否成功bool has_value() const noexcept是否持有正常值
隐式 bool 转换explicit operator bool() const noexcept同 has_value
获取值T& value()获取正常值的引用(失败抛异常)
获取错误const E& error() const获取错误的引用
解引用T& operator*()获取正常值(未检查,行为未定义若错误)
链式变换auto transform(F&& f)若有值,对值应用 f 并包装结果
链式错误处理auto and_then(F&& f)若有值,调用 f 并返回其 expected 结果
错误分支auto or_else(F&& f)若有错误,调用 f 处理错误
错误变换auto transform_error(F&& f)若有错误,对错误应用 f
创建成功值std::expected<T, E>(value)工厂:直接构造成功
创建错误值std::unexpected{err}工厂:构造 unexpected 用于隐式转 expected

最小示例

cpp
// Standard: C++23
#include <expected>
#include <iostream>
#include <string>

std::expected<int, std::string> divide(int a, int b) {
    if (b == 0) return std::unexpected{"division by zero"};
    return a / b;
}

int main() {
    auto r1 = divide(10, 3);
    if (r1) std::cout << *r1 << "\n"; // 3

    auto r2 = divide(10, 0);
    if (!r2) std::cout << r2.error() << "\n"; // division by zero

    // 链式调用
    auto r3 = divide(20, 4).transform([](int v) { return v * 2; });
    std::cout << *r3 << "\n"; // 10
}

嵌入式适用性:高

  • 零开销抽象:大小等于 sizeof(T) + sizeof(E) 加一个判别标志,无堆分配
  • 替代异常处理机制,适合禁用异常的嵌入式环境(-fno-exceptions
  • 比 error code + output parameter 模式类型安全,强制调用方处理错误
  • 链式操作(transform/and_then)可组合复杂业务流程,保持代码线性可读

编译器支持

GCCClangMSVC
121619.36

另见


部分内容参考自 cppreference.com,采用 CC-BY-SA 4.0 许可

基于 VitePress 构建