Search code examples
c++c++11boostmove-semanticsboost-optional

Returning rvalue reference from a function that returns Boost optional


As of Boost 1.56, Boost optional supports move semantics. In that case, is the following construct meaningful?

boost::optional<SomeType> getValue()
{
  if (value_available) {       // value_available is a boolean
    return std::move(value);   // value is of type SomeType
  } else {
    return boost::none;
  }
}

Solution

  • Yes it would be meaningful. It means you move from value in case you have it.

    However, it surprises me that you return as optional, when it appears that semantically the class already contains an optional value (value_available is the indicator of that).

    So, instead I'd suggest to store value as optional<T> already and just return that

    return value; // already optional!
    

    In this case you get proper move semantics and RVO for free. Of course if value is not a local or temporary, you need to say

    return std::move(value);
    

    (Sidenote: I don't agree with the other answer that this is only useful if getValue() is called only once. If your type has a well-defined "default" state to return to after move, then it could become a sort of "1-element queue".)

    In such a case it might be nice to explicitly uninitialize the source value before returning. I think it is tricky to implement this exchange in an exception safe way though.

    Consider renaming the function to e.g. popValue(), extractValue() or consume() to explicitly mention the fact that using this function moves from internal object state. Of course, some warning is already implicitly present in the fact that the member function is not const but good naming is important too