# result<>

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;
```

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.
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`

in standalone Outcome, or to `boost::system::error_code`

in Boost.Outcome^{1}. The third parameter (`NoValuePolicy`

) 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.
Triviality, complexity and constexpr-ness of each operation (construction, copy construction, assignment,
destruction etc) is always the intersection of the corresponding operation in `T`

and `EC`

,
so for example if both `T`

and `EC`

are literal types, so will be `result<T, EC, NVP>`

.
Additionally, if both `T`

and `EC`

have standard layout, `result<T, EC, NVP>`

has standard layout;
thus if both `T`

and `EC`

are C-compatible, so will `result<T, EC, NVP>`

be C-compatible.

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 functions:

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

- You can mandate a choice using
`std_result<T>`

or`boost_result<T>`

.^{[return]}