TRY is greedy
OUTCOME_TRYV(expr)/OUTCOME_TRY(expr)
has ‘greedier’ implicit conversion semantics than
basic_result<T, E, NoValuePolicy>
. For example, this code won’t compile:
outcome::result<int, std::error_code> test(outcome::result<int, std::errc> r)
{
return r; // you need to use explicit construction here
// i.e. return outcome::result<int>(r);
}
This is chosen because there is a non-trivial conversion between std::errc
and std::error_code
,
so even though that conversion is implicit for std::error_code
, Outcome does not expose the
implicitness here in order to keep the implicit constructor count low (implicit constructors
add significantly to build times).
The TRY
operation is more greedy though:
outcome::result<int, std::error_code> test(outcome::result<int, std::errc> r)
{
OUTCOME_TRY(r); // no explicit conversion needed
return r.value();
}
This is because result<int, std::error_code>
will implicitly construct from anything which
either int
or std::error_code
will implicitly construct from. However,
result<int, std::error_code>
will not implicitly construct from result<int, std::errc>
.
Thus bear this in mind during usage: TRY
is greedier for implicit conversions than the Outcome
types themselves.