It is recommended that you refer to entities from this Outcome 2.0 via the following namespace alias:

```
namespace outcome = OUTCOME_V2_NAMESPACE;
```

As patches and modifications are applied to this library, namespaces get permuted in order
not to break any backward compatibility. At some point namespace `outcome::v2`

will be defined,
and this will be the prefered namespace. Until then `OUTCOME_V2_NAMESPACE`

denotes the most recently
updated version, getting closer to `outcome::v2`

.

`result<>`

We will define a function that converts an `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;
```

Class template result<T, EC, NVP>
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.
The second (`EC`

) is the type of object containing information about the reason
for failure when the function fails. A result object stores either a `T`

or an
`EC`

at any given moment, and is therefore conceptually similar to `variant<T, EC>`

. `EC`

is defaulted to `std::error_code`

. The third parameter (`NVP`

) is called a
no-value policy. We will cover it later.

If both `T`

and `EC`

are trivially copyable, `result<T, EC, NVP>`

is also trivially copyable.

Now, we will define an enumeration describing different failure situations during conversion.

```
enum class ConversionErrc
{
Success = 0, // 0 should not represent an error
EmptyString = 1, // (for rationale, see tutorial on error codes)
IllegalChar = 2,
TooLong = 3,
};
// all boilerplate necessary to plug ConversionErrc
// into std::error_code framework
```

Assume we have plugged it into `std::error_code`

framework, as described in this section.

One notable effect of such plugging is that `ConversionErrc`

is now convertible to `std::error_code`

.
Now we can implement function `convert`

as follows:

```
outcome::result<int> convert(const std::string& str) noexcept
{
if (str.empty())
return ConversionErrc::EmptyString;
if (!std::all_of(str.begin(), str.end(), ::isdigit))
return ConversionErrc::IllegalChar;
if (str.length() > 9)
return ConversionErrc::TooLong;
return atoi(str.c_str());
}
```

`result<T, EC>`

is convertible from any `T2`

convertible to `T`

as well as any `EC2`

convertible to `EC`

,
provided that there is no constructability possible in either direction between `T`

and `EC`

. If there is,
all implicit conversion is disabled, and you will need to use one of the tagged constructors:

```
outcome::result<int> r {outcome::in_place_type<std::error_code>, ConversionErrc::EmptyString};
outcome::result<int> s {outcome::in_place_type<int>, 1};
```

Or use helper factory functions:

```
outcome::result<int> r = outcome::failure(ConversionErrc::EmptyString);
outcome::result<int> s = outcome::success(1);
```