In C++23, given:
expected<A, string> getA(const X& x);
expected<B, string> getB(const Y& y);
C compute_all(const A& a, const B& b);
Is there a way to avoid a classic style check like:
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);
and write something like
expected<C, string> final_ret = magic_apply(compute_all, getA(x), getB(y))
This is an idea of implementation of magic_apply but I need something more generic (perhaps using variadic templates), that allows passing to compute_all
some parameter that is not an 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());
}
Does some feature already exist in the language I could use to write this?
liftA2
and in Rust the!
syntax expands to the pattern you wrote. C++ has neither of these things, I'm afraid. – Rehashstd::array<std::optional<Err>, N>
, and if no error just callreturn func(expecteds.value()...)
– Fernfernacompute
function per object is called from a loop. Perfectly readable code and no need to invoke the nine hells of template meta programming. – Somnusreturn frobnicate(get_foo(), get_bar(), get_baz());
, but those can all fail – Sosaget_foo
returns the first parameter offrobnicate
on the happy path, and an error otherwise. dittoget_bar
andget_baz
. Those parameters aren't the same type, and there is a fixed number of them – SosaR frobnicate(A, B, C)
when you haveexpected<A, Err>, expected<B, Err>, expected<C, Err>
, and end up with anexpected<R, Err>
(or possiblyexpected<R, composite<Err>>
) – Sosacartesian_product
for functions of multiple arities (and the appropriate number of input vectors), instead ofcartesian_product_binary
,cartesian_product_ternary
etc. – Sosa