add tag
Jonathan Mee
[`std::optional`]( is described as superior to `std::pair<T, bool>` because it:

> Handles expensive-to-construct objects well and is more readable, as the intent is expressed explicitly

Why then wouldn't we prefer a `T*` which could be `nullptr`?
Top Answer
Jonathan Mee
`std::optional<T>` has been written as an alternative to using `T*` and null-checking to determine object viability. `std::optional<T>` is conditionally preferred over `T*` for the same reason [smart pointers]( are  conditionally preferred, to:

> Reduce bugs caused by the misuse of pointers, while retaining efficiency

It should be noted that neither `std::optional<T>` nor `T*` result in a "reduction of bugs" if there exists a signaling value in the range of `T` which does not limit the valid values. (For example the standard prefers: [`std::string::npos`]( as an invalid signal over using: `std::optional<size_type>`)

Just like smart pointers, `std::optional<T>` incurs a cost. It is implemented as an object containing both a `bool` and a `T` member, similar to `std::pair<T, bool>`, however the `T` member need only be initialized when the `bool` member is `true`.

# When does the "reduction in bugs" justify the use of `std::optional<T>` over a null-checked `T*`?

1. In [lazy initialization of `T`]( _where no other variable denoting whether `T` is initialized exists_
1. As [a function's return type](, because using a `T*` return type requires the caller to read the function to determine whether or not the returned object should be deleted

This room is for discussion about this question.

Once logged in you can direct comments to any contributor here.

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.