在 c++ 23 中,给出:
namespace std;
expected<A, string> getA(const X& x);
expected<B, string> getB(const Y& y);
C compute_all(const A& a, const B& b);
有没有办法避免经典风格检查,例如:
auto a_ret = getA(x);
if (!a_ret)
return a_ret.error();
auto b_ret = getB(y);
if (!b_ret)
return b_ret.error();
C final_ret = compute_all(*a_ret, *b_ret);
并写下类似的内容
expected<C, string> final_ret = magic_apply(compute_all, getA(x), getB(y))
这是 magic_apply 的实现想法,但需要更通用的东西(可变参数模板?传递给compute_all一些不是 std::expected 的参数?)
template<typename Func, typename A, typename B, typename Err>
auto magic_apply(Func func, const std::expected<A, Err>& a, const std::expected<B, Err>& b)
->
std::expected<decltype(func(a.value(), b.value())), Err>
{
if(!a) {
return std::unexpected{ a.error() };
}
if(!b) {
return std::unexpected{ b.error() };
}
return func(a.value(), b.value());
}
我感觉自己滥用了功能模式,或者语言中缺少一些功能。
是否已经存在类似的东西?
由于
std::expected<T,E>::value
抛出异常,你可以这样做:
template<typename Func, typename A, typename B, typename Err>
auto magic_apply(Func func, const std::expected<A, Err>& a, const std::expected<B, Err>& b)
->
std::expected<decltype(func(a.value(), b.value())), Err> {
try {
return func(a.value(), b.value());
} catch (const std::bad_expected_access<Err>& e) {
return std::unexpected(e);
}
}