

新闻资讯
技术百科std::expected 是 C++23 引入的值优先、错误显式的标准化错误处理工具,用于替代返回码或自定义包装类型,适用于文件解析、配置读取等可预期失败场景,不取代异常。
std::expected 是 C++23 引入的标准化错误处理工具,用来替代传统返回码、异常或自定义包装类型(如 std::optional + 状态码),实现“值优先、错误显式”的函数返回风格。它不是万能异常替代品,而是为预期可能失败但不属异常语义的场景(比如文件解析、配置读取、网络响应解码)提供更清晰、更安全、更可组合的返回接口。
模板形式为 std::expected,其中 T 是成功时携带的值类型,E 是失败时携带的错误类型(通常为 std::error_code、std::string 或自定义错误枚举)。它内部只保存 T 或 E 中的一个,不可同时存在。
std::expected ok{42}; 或 std::make_expected(42);
std::expected err{std::unexpect, "file not found"}; 或 std::make_unexpected("timeout");
if (res.has_value()) { /* 成功 */ } else { /* 失败,用 res.error() 取错误 */ }
当多个操作需按顺序执行、且任一环节失败就终止并透传错误时,and_then 是核心工具。它只在当前为 value 时调用传入的函数,并自动将该函数返回的 expected “扁平化”——避免嵌套 expected。
auto res = parse_json(str).and_then(validate_schema).and_then(extract_user_id);std::expected,类型需兼容(错误类型最好
一致)unexpected,后续函数不执行,整个链直接返回该错误当需要对特定错误做修复、降级或日志记录时,or_else 接收一个以 const E& 为参数的函数,返回新的 expected;而 value_or 提供简单默认值兜底(仅适用于可默认构造或提供默认值的 T)。
auto id = fetch_user_id().or_else([](const std::error_code& ec) { return fallback_user_id(); });int timeout = get_timeout_config().value_or(3000); // 失败时用 3000value_or 会强制移动或拷贝 T,若 T 构造代价高或不可拷贝,应改用 and_then + 显式判断std::expected 不取代异常,也不等价于 std::optional:
expected 用于业务逻辑中可预见、可分类处理的失败(如“用户不存在”、“配置缺失”)std::optional 只能表达“有/无值”,无法携带错误原因;expected 明确区分“成功值”和“失败原因”,支持错误类型多态和模式匹配(配合 std::visit 自定义访问器)expected parse(const std::string&) 比 bool parse(..., Data& out) 或抛异常更直观、更易组合不复杂但容易忽略:别把所有函数都改成 expected,优先用于 I/O、解析、校验等天然带失败语义的函数;保持错误类型轻量、可比较、可输出;搭配 std::error_code + std::system_category() 或自定义错误类别,能更好融入系统生态。