As much as Outcome originated in a negative reaction to the then originally proposed std::expected<T, E>, LEAF originated in a negative reaction to Outcome. Some of the perceived issues with Outcome were (LEAF’s own rendition of this can be viewed here):

LEAF therefore looks more like standard C++ exception handling, but without the non-deterministic sad path at the cost of a slight impact on happy path runtime performance. LEAF’s current design was completed in 2020.

If you need an error handling framework which has predictable sad path overhead unlike C++ exceptions, but you otherwise want similar syntax and use experience to C++ exceptions, LEAF is a very solid choice.



  1. In Outcome, it is strongly recommended that one chooses a single universal error type for all public APIs such as std::error_code or error from Experimental.Outcome, so if the programmer is disciplined then the function signature does not expose internal error types. Such single universal error types type erase the original error object, but still allow the original error object to be inspected. This avoids ‘exception specifications’ which are widely known to not scale well. [return]
  2. A global synchronised ring buffer implementation does not ship with LEAF, however LEAF exposes customisation points for a bespoke thread local storage implementation which makes implementing one very straightforward. [return]
  3. std::error_code construction touches a magic static or calls an extern function, and therefore Outcome when combined with std::error_code also sees a codegen pessimisation. Experimental Outcome’s error fixes this historical oversight. [return]