How to move from std::optional<T>

boost-optional, c++, c++14, std

Solution

It is valid to move from `optional<T>::value()` since it returns a mutable reference and the move does not destroy the object. If the `optional` instance is not engaged, `value()` will throw a `bad_optional_access` exception (§20.6.4.5).

You explicitly check whether the option is engaged:

if (content)
    Process(move(*content));

But you don't use the member `value()` to access the underlying `T`. Note that `value()` performs a check internally before returning a valid `T&`, unlike `operator*` which has a precondition that the `optional` instance shall be engaged. This is a subtle difference, but you use the right idiom:

if (o)
  f(*o)

as opposed to

if (o)  // redundant check
  f(o.value())

In Boost, the situation is a little different: first, there exists no member function called `value()` that provides checked access. (A `bad_optional_access` exception simply does not exist). The member `get()` is just an alias for `operator*` and always relies on the user checking that the `optional` instance is engaged.

Problem

Consider the following example where we parse data and pass the result to the next function: ``` Content Parse(const std::string& data); void Process(Content content); int main() { auto data = ReadData(); Process(Parse(data)); } ``` Now let's change the code using `std::optional` to handle a failed parsing step: ``` optional<Content> Parse(const std::string& data); void Process(Content content); int main() { auto data = ReadData(); auto content = Parse(data); if (content) Process(move(*content)); } ``` Is it valid to move from `optional<T>::value()`? If it's ok for `std::optional` is it valid for `boost::optional` as well?

Original source