std::expected是 C23 标准库引入的一个类模板用于表示一个操作可能成功并返回一个值也可能失败并返回一个错误信息。它提供了一种类型安全、语义明确且零成本的现代错误处理机制旨在替代传统的错误码和异常。 为什么需要 std::expected在std::expected出现之前C 的错误处理方式各有痛点错误码 (Error Codes):容易被调用者忽略且无法携带丰富的错误上下文信息。异常 (Exceptions):虽然能携带详细信息但存在性能开销栈展开并且会使控制流变得隐式和难以追踪。在一些对性能敏感或禁用异常的环境中如游戏引擎、嵌入式系统不适用。std::optionalT:只能表示“有值”或“无值”但无法说明“为什么无值”。std::expectedT, E完美地解决了这些问题。它明确表示一个操作要么返回一个类型为T的成功值要么返回一个类型为E的错误值。这迫使调用者必须显式地处理失败的情况从而提高了代码的健壮性。 基本用法std::expected的使用非常直观。#include expected #include iostream #include string // 一个可能失败的函数除法运算 std::expecteddouble, std::string divide(double a, double b) { if (b 0.0) { // 返回一个错误 return std::unexpected(除数不能为零); } // 返回成功值 return a / b; } int main() { auto result divide(10.0, 2.0); // 1. 检查是否包含有效值 if (result.has_value()) { // 2. 获取成功值 std::cout 结果: result.value() std::endl; } else { // 3. 获取错误信息 std::cout 错误: result.error() std::endl; } // 更简洁的布尔检查 auto bad_result divide(5.0, 0.0); if (bad_result) { std::cout 结果: *bad_result std::endl; // 解引用操作符 } else { std::cout 错误: bad_result.error() std::endl; } return 0; }✨ 核心优势函数式组合std::expected最强大的地方在于它支持链式调用可以将多个可能失败的操作优雅地组合在一起避免深层的if-else嵌套。and_then:如果当前expected对象包含值则调用提供的函数该函数也必须返回一个std::expected如果当前是错误则直接短路传递错误。or_else:如果当前expected对象包含错误则调用提供的函数进行错误恢复或转换。transform:如果当前包含值则对值进行转换。// 假设我们有以下几个可能失败的函数 std::expectedstd::string, std::error_code read_file(const std::string path); std::expectedConfig, std::error_code parse_json(const std::string json); std::expectedvoid, std::error_code validate_config(const Config cfg); // 使用 and_then 进行链式调用 auto config_result read_file(config.json) .and_then(parse_json) .and_then(validate_config); if (!config_result) { // 任何一步失败都会到达这里 std::cerr 配置加载失败: config_result.error().message() std::endl; } 与其他机制的对比特性std::expectedT, Estd::optionalT异常 (throw/catch)核心语义成功(T) 或 失败(E)有值 或 无值正常流 或 意外中断错误信息携带具体错误对象 (E)无携带异常对象性能零成本无栈展开零成本有开销栈展开控制流显式编译器强制检查显式隐式难以追踪✅ 何时使用std::expected适用于处理那些可预期的、常规的、可恢复的错误。I/O 操作文件不存在、网络超时、权限不足。数据解析JSON 格式错误、字符串转换数字失败。业务逻辑校验用户输入不符合规则。不应该用它来处理程序逻辑缺陷或资源耗尽等意外的、不可恢复的灾难性错误如内存分配失败std::bad_alloc、数组越界这些情况仍然应该交给异常或std::abort处理。