如何简化返回std::expected的函数调用结果的拆包逻辑?
简化std::expected拆包逻辑的方案
你的核心问题是std::expected<T, E>会被直接存入std::any,导致外层std::expected<std::any, E>的值类型是整个内层expected而非T。手动拆包的逻辑可以通过通用转换函数来简化,不需要重复编写判断逻辑。
通用转换函数实现
写一个模板函数,自动处理std::expected的拆包和错误传递:
#include <expected> #include <any> // 自定义错误类型,根据实际场景调整 struct Fault { /* ... */ }; template<typename T, typename E> std::expected<std::any, E> to_any_expected(std::expected<T, E> exp) { if (exp.has_value()) { // 将内层值存入std::any并返回 return std::any{std::move(exp.value())}; } // 直接传递错误 return std::unexpected{std::move(exp.error())}; } // 内层函数示例 std::expected<int, Fault> do1() { bool error = false; // 模拟无错误场景 if (error) { return std::unexpected<Fault>({}); } return 23; } // 简化后的doN std::expected<std::any, Fault> doN(int n) { switch (n) { case 1: return to_any_expected(do1()); // case 2: return to_any_expected(do2()); default: return std::unexpected<Fault>({}); } }
效果说明
调用doN(1).value()时,类型会是int(被std::any包裹),和你手动拆包的效果完全一致,但不需要重复编写has_value()判断和错误传递的代码。
为什么直接返回不行?
因为std::expected<int, Fault>可以隐式转换为std::any,所以当你直接return do1()时,外层std::expected<std::any, Fault>会把整个内层expected对象作为值存入std::any,而非拆包后的int值。通用函数的作用就是显式完成拆包动作,避免这种隐式转换带来的不符合预期的行为。
内容的提问来源于stack exchange,提问作者Gashmob
相关产品推荐
相关产品推荐

