std::expected 没有 value_or 成员函数;它仅提供 has_value() 和 value(),需手动结合三元运算符实现等效逻辑,如 exp.has_value() ? exp.value() : 42。

std::expected::value_or 不存在,别被名字骗了
直接说结论:std::expected 没有 value_or 成员函数。这是常见误解——它模仿的是 std::optional 的接口,但标准委员会没给 std::expected 加这个方法。你写 exp.value_or(42) 会编译失败,报错类似:error: 'value_or' is not a member of 'std::expected<int std::string>'</int>。
正确做法:用 value_or 等效逻辑手动实现
你需要显式检查是否包含值,再决定返回什么。核心是 has_value() + 三元运算符或 if 分支:
int x = exp.has_value() ? exp.value() : 42;
注意几点:
-
exp.value()在无值时抛std::bad_expected_access<e></e>,所以不能无条件调用 - 如果
E(错误类型)不可默认构造,std::expected<t e>::value_or</t>无法实现为成员函数——这是标准不提供它的根本原因 - 若想复用逻辑,可封装成自由函数:
template <class t class e u> constexpr T value_or(const std::expected<t e>& e, U&& def) { return e.has_value() ? e.value() : static_cast<t>(std::forward<u>(def)); }</u></t></t></class>
和 std::optional::value_or 的关键差异
表面看都是“取值或默认”,但语义不同:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
std::optional::value_or接受任意类型U,只要能隐式转为T;而std::expected的等效逻辑需你自行处理类型转换 -
std::optional的空状态是“无值”,std::expected的“无值”意味着“有错误”,错误值本身可能携带上下文(比如std::string描述),直接丢弃它用默认值,有时掩盖问题 - 性能上无差别,都是一次
has_value()判断 + 条件分支
更安全的替代:用 and_then 或 transform 处理默认逻辑
如果你的默认值依赖于错误内容(比如根据错误码返回不同默认值),硬写三元运算符会变复杂。这时更适合用 and_then 或 transform:
// 若成功,返回 value;否则根据 error 返回对应默认值
auto result = exp.transform([](int v) { return v; })
.or_else([](const std::string& err) -> int {
if (err == "timeout") return -1;
if (err == "not_found") return 0;
return 42;
});
这比层层嵌套的 if 更清晰,也避免重复调用 value() 或误判状态。
真正容易被忽略的是:std::expected 的设计哲学是“显式处理错误”,不是“悄悄兜底”。用 value_or 风格逻辑前,先确认你真的想忽略错误细节。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










