TRY operations
In the implementation of function print_half
we have seen the usage of the macro OUTCOME_TRYV(expr)/OUTCOME_TRY(expr)
:
OUTCOME_TRY (auto i, BigInt::fromString(text));
The OUTCOME_TRY
macro uses C macro overloading to select between two implementations based on the number of
input parameters. If there is exactly one input parameter i.e. without the i
, the control statement is
roughly equivalent to:
auto __result = BigInt::fromString(text);
if (!__result)
return __result.as_failure();
Where __result
is a compile time generated unique name. This single argument form is equivalent to
OUTCOME_TRYV(expr)
, incidentally.
If there are between two and eight parameters, this control statement is roughly equivalent to:
auto __result = BigInt::fromString(text);
if (!__result)
return __result.as_failure();
auto i = __result.value();
So here i
as the first C macro parameter is set to the value of any successful result.
C macro overloads are provided for up to eight arguments. To prevent the confounding of the C preprocessor by commas in template specifications causing more than eight arguments appearing to the C preprocessor, you should consider wrapping the second argument in brackets.
If you are within a C++ Coroutine, you ought to use OUTCOME_CO_TRYV(expr)/OUTCOME_CO_TRY(expr)
instead.
Compiler-specific extension: OUTCOME_TRYX
This macro makes use of a proprietary extension in GCC and clang, and is not
portable. The macro is not made available on unsupported compilers,
so you can test for its presence using #ifdef OUTCOME_TRYX
.
GCC and Clang provide an extension to C++ known as
statement expressions.
These make it possible to use a more convenient macro: OUTCOME_TRYX
, which is an expression. With the above macro, the above declaration of variable i
can be rewritten to:
int i = OUTCOME_TRYX (BigInt::fromString(text));
This has an advantage that you can use it any place where you can put an expression, e.g., in “simple initialization”:
if (int i = OUTCOME_TRYX(BigInt::fromString(text)))
use_a_non_zero_int(i);
or in as a subexpression of a bigger full expression:
int ans = OUTCOME_TRYX(BigInt::fromString("1")) + OUTCOME_TRYX(BigInt::fromString("2"));
There is also an OUTCOME_CO_TRYX(expr)
if you are inside a C++ Coroutine.