Extending `OUTCOME_TRY`

Outcome’s OUTCOME_TRY(var, expr) operation is fully extensible to accept as input any foreign types. It already recognises types matching the ValueOrError<T, E> concept, which is to say all types which have: A public .has_value() member function which returns a bool. In order of preference, a public .assume_value()/.value() member function. In order of preference, a public .as_failure()/.assume_error()/.error() member function. This should automatically handle inputs of std::expected<T, E>, and many others, including intermixing Boost. »

Inspecting result<T, EC>

Suppose we will be writing a function print_half that takes a std::string representing an integer and prints half the integer: outcome::result<void> print_half(const std::string& text); View this code on Github The type result<void> means that there is no value to be returned upon success, but that the operation might still fail, and we may be interested in inspecting the cause of the failure. The class template result<> is declared with the attribute [[nodiscard]], which means the compiler will warn you if you forget to inspect the returned object (in C++ 17 or later). »

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 (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. »


We will define a function that converts a std::string to an int. This function can fail for a number of reasons; if it does we want to communicate the failure reason. outcome::result<int> convert(const std::string& str) noexcept; View this code on Github Template alias result<T, E = varies, NoValuePolicy = policy::default_policy<T, E, void>> has three template parameters, but the last two have default values. The first (T) represents the type of the object returned from the function upon success. »