Outcome: reporting C++ function failures as return values, not exceptions
Provides very lightweight outcome<T> and result<T> (non-Boost edition)
At a glance
- What is it?
- Outcome is a C++14 library for propagating and handling failure as a value, offered as a single header file with signed releases. It fits codebases that must build with exceptions disabled or that need control flow to be auditable.
- Who is it for?
- Outcome fits C++ codebases that compile with exceptions turned off, that need every failure path visible to a reviewer, or that carry failure reports across thread and task boundaries. It does not fit code that has already settled on exceptions as its only error mechanism and has no appetite for changing call sites.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Failure arrives as a value the caller is meant to look at
Outcome is a C++14 library for reporting and handling function failures, and the project describes it as a substitute for, or a complement to, the exception handling mechanism. That word, substitute, is the load bearing one. With exceptions, a failure unwinds the stack from a point the caller cannot see, and the handler sits at a distance from the throw site. With Outcome, the failing function returns a value that carries the failure, and the caller is positioned to branch on it immediately. The library provides the outcome type and a result type for values that can be either a success or a failure, and the repository description describes both as deliberately lightweight. The interest for most teams is not philosophical. It is that the second question a reviewer asks, what happens when this fails, gets an answer written on the same line as the call rather than somewhere up the stack.
The four situations the project names for choosing Outcome
The README lists the contexts where exception handling is unsuitable, and the list is more useful than the marketing sentence. The first is the relative cost of throwing and catching, which matters in hot paths where failure is expected rather than exceptional. The second is auditability: making some or all control paths explicitly detailed, as opposed to the hidden control paths that exceptions introduce because a throw can come from anywhere. The third is company policy that requires compiling with exceptions disabled. The fourth is a code base that was never designed with exception safety in mind, which is the case where retrofitting exceptions is more work than adopting a return value convention. A fifth case is aimed at frameworks that implement exception handling themselves and cannot afford exceptions inside, such as propagating failure reports across threads, tasks and fibers. Read together, these describe a library for code whose error paths have to be visible, not merely for code that wants to avoid try and catch.
The single header file is regenerated on every commit
Version 2 of Outcome ships in single header form, and the documentation is clear that this file is regenerated per commit. The practical consequence is that there is no stable download URL for a specific version: the raw file on the master branch moves. To fetch it on Linux, the documentation gives a wget command.
wget https://github.com/ned14/outcome/raw/master/single-header/outcome.hppOn BSD, the equivalent is fetch.
fetch https://github.com/ned14/outcome/raw/master/single-header/outcome.hppAnd for anyone with curl installed, the same file can be pulled with a remote name option so the local file keeps its name.
curl -O -J -L https://github.com/ned14/outcome/raw/master/single-header/outcome.hppOtherwise the instruction is simply to download the raw file and place it wherever it suits you, which is a fair description of the header only library model. Users debugging in Microsoft Visual Studio are pointed at a separate debugger visualisation file, outcome.natvis, which can be included into the build so the failure value renders in the debugger rather than as a wall of text. The repository also carries a CMakeLists.txt, a .quickcpplib file and a conan directory, so a packaged install path exists alongside the header drop.
Commits and tags can be checked against a published GnuPG key
Because the single header file is fetched straight from a moving branch, the project puts weight on verification. The documentation states that commits and tags in the repository can be verified using a PGP public key block published in the README, generated with GnuPG v2 and identified as Ned14's key. The key identity in the block matches the person who maintains the Boost.Outcome project, and the block is meant to be imported into your own keyring. Verification matters here for a concrete reason rather than a ceremonial one: the single header path gives you a file that was generated from some commit, and without a signature check there is nothing tying that file to a tag you chose. The tags on the repository are named after the commit they point at, which gives you a second handle: pick a tag, verify it against the key, and then fetch the header from that tag instead of from master.
The same suites run on Linux, Mac OS and Windows in CI
The repository layout shows a continuous integration setup with separate workflows for documentation, installability, and unit tests on Linux, Mac OS and Windows, and the README badge table repeats the same matrix for both the master and develop branches. A CTest configuration file is present along with CTestConfig.cmake, which points the test results at the public CTest dashboard under the project name Boost.Outcome. Two consequences follow. First, a header only library that claims to be portable is checked on all three desktop platforms rather than on one, so a porting mistake tends to surface in CI rather than on your build machine. Second, the branch naming is unusual and worth internalising before you contribute: the default branch of the repository is develop, while the documentation and the single header download both point at master. The two are not interchangeable, and the release process described below depends on which one you fetched.
Releases are tarballs named after a commit whose tests passed
The GitHub releases for this project are not version numbers. The listed releases are named All tests passed followed by a full commit hash, and the dates attached to them run through May and June 2026. The README links to those releases as the place to find all tests passing source tarballs, so the naming convention is the release policy: a tarball exists when a particular commit passed the suite, and the commit hash in the name is how you identify it. For a user, that is convenient, because the artefact and the commit are the same thing, with nothing to reconcile. For a maintainer, it means the version number people cite in bug reports is a hash rather than a semantic version, which changes how downstream packaging has to track releases. The repository also carries an abi-compliance directory and a benchmark directory, and an attic directory, which suggests a history of versions kept for comparison rather than deleted outright.
Where Outcome is the wrong choice
There are two honest limits. The first is that every call site changes. A function that throws can keep its signature and let the failure travel invisibly, whereas an Outcome returning function changes its return type and forces the caller to handle the failure, so adopting it in an existing code base is a mechanical but wide edit rather than a drop in replacement. The library can be used as a complement instead, which limits the blast radius, and the README names both roles. The second is the licensing question, and it needs reading rather than assumption. The repository carries a Licence.txt file, and GitHub classifies the licence as a custom one it cannot categorise, which is not the same as saying it is permissive. The topics list the library alongside boost, and the tree contains a .boostify file and a boostify directory, so the code descends from the Boost.Outcome work even though the repository presents itself as the non Boost edition. Read Licence.txt before you copy a header into a commercial product, and note that the single header file being regenerated per commit means you should pin it to a verified tag rather than to the branch.
Editorial conclusion
Outcome fits C++ codebases that compile with exceptions turned off, that need every failure path visible to a reviewer, or that carry failure reports across thread and task boundaries. It does not fit code that has already settled on exceptions as its only error mechanism and has no appetite for changing call sites. Before adopting it, read Licence.txt rather than assuming a Boost licence, pin the single header to a tagged release instead of to the master branch, since that file is regenerated on every commit, and decide how much of your existing call surface you are willing to change.
Frequently asked questions
How do I install Outcome without building it from source?
Version 2 ships as a single header file. The documentation gives wget on Linux, fetch on BSD and a curl command with a remote name option, all pointing at single-header/outcome.hpp on the master branch.
Which C++ standard does Outcome require?
The README describes Outcome as a C++14 library for reporting and handling function failures.
Is Outcome the same as Boost.Outcome?
The repository description calls this the non Boost edition and provides lightweight outcome and result types. The tree still contains a .boostify file and a boostify directory, and the CTest dashboard entry is registered under the project name Boost.Outcome.
How are Outcome releases named?
The releases are named All tests passed followed by the commit hash, and the README points to them as the place to find all tests passing source tarballs. The commit hash in the name identifies the artefact.
How do I verify the Outcome source I downloaded?
The README states that commits and tags in the repository can be verified using a GnuPG v2 PGP public key block published there, which you import into your own keyring and check the tag against.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ned14-outcome)Was this useful?