std::expected 是用于明确区分成功值与具体错误原因的类型,适用于i/o等需避免异常和全局错误码的场景;构造用 std::expected(t) 或 std::unexpected(e),检查用 has_value(),链式调用用 and_then。

std::expected 是什么,什么时候该用它
它不是 std::optional 的替代品,也不是 std::variant 的简化版。当你需要明确区分「成功返回值」和「具体错误原因」(比如 std::errc::no_such_file 或自定义错误类型),且不想抛异常、也不愿用出参或全局错误码时,std::expected 才是合适选择。
常见误用场景:把 std::expected<void err></void> 当成“带错误码的 void 函数”——这可行但容易掩盖控制流;更典型的是 std::expected<:string std::error_code></:string> 用于文件读取、网络请求等 I/O 操作。
构造和检查 std::expected 的正确写法
别直接用 std::make_expected(C++23 没这东西);构造靠 std::expected<t e>(T)</t> 或 std::unexpected<e>(E)</e>:
std::expected<int std::error_code> parse_int(std::string_view s) {
try {
return std::stoi(std::string(s)); // 成功:隐式转为 expected<int ...>
} catch (const std::invalid_argument&) {
return std::unexpected(std::make_error_code(std::errc::invalid_argument));
}
}</int></int>
检查状态必须用 has_value(),而不是 operator bool() ——后者在 C++23 中已被弃用,编译会报错:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
if (e.has_value())✅ -
if (e)❌(过时语法,部分标准库实现已禁用) -
e.value()只能在has_value() == true时调用,否则抛std::bad_expected_access
链式调用中用 and_then 处理连续操作
and_then 不是 map:它接收一个返回 std::expected 的函数,自动展开嵌套,避免手动解包。适合“读文件 → 解析 JSON → 提取字段”这类线性流程:
auto result = read_file("config.json")
.and_then([](std::string s) { return parse_json(s); })
.and_then([](json_obj j) { return extract_port(j); }); // 返回 expected<int err></int>
注意点:
- lambda 返回类型必须严格匹配
std::expected<u e></u>,不能是U或std::expected<u othere></u> - 如果中间某步失败(返回
std::unexpected),后续 lambda 完全不执行,原错误被透传 - 没有
or_else(C++23 标准没提供),错误恢复需手动判断!e.has_value()
与 error_code、exception 混用时的兼容陷阱
std::expected 和异常不是互斥方案,但混用容易出问题:
- 不要在
and_then里 throw 异常:一旦抛出,std::expected无法捕获,程序终止 -
std::error_code是推荐的错误类型,但别传std::system_category()以外的 category——某些平台对非标准 category 的message()实现为空 - 若函数原本用
throw报错,强行改成std::expected返回,记得同步更新所有调用点;漏改一处.value()就可能 crash
最易忽略的一点:std::expected 的拷贝/移动语义依赖于 T 和 E 是否可拷贝。如果错误类型是 std::unique_ptr<myerror></myerror>,那这个 std::expected 就不可拷贝——而很多算法(如 std::vector::push_back)会触发拷贝。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










