This is an academic question. The std::optional<T> type has a T && value() && method. I have the following definitions:
class A { ... };
void f(A &&a);
And the following program:
std::optional<A> optA;
optA = A(1337);
f(std::move(optA).value()); // OPTION 1
f(std::move(optA.value())); // OPTION 2
std::cout << optA.has_value() << std::endl;
Is there any meaningful difference between OPTION 1 and OPTION 2? For OPTION 1 will I have 1, 0 or unspecified as output? According to my tests has_value() remained true in both cases.
Is there any possible situation where value() && makes a difference over std::move and value()?
There's no difference between std::move(optA).value() and std::move(optA.value()). value() just returns a glvalue referring to the contained value, and either you can have value() return an lvalue which is then converted to an xvalue by std::move, or you can call std::move first and have value() give you an xvalue right away (in reality, the conversion from lvalue to xvalue will be occurring somewhere within the value() method itself). The ref-qualified overloads are obviously not very useful in this simple case, but can be useful when the optional was passed by forwarding reference O&& o, and you want std::forward<O>(o).value() to "do the right thing".
f(std::move(optA).value()); // OPTION 1
You "moved" optA, but this doesn't mean you changed it. Usually you shouldn't use value after it was "moved out", as it's in a valid but indeterminate state. std::move is just a type cast (exactly same as static_cast<A&&>(optA)). Moving constructor wasn't called because no new instance of std::optional<A> was created. Hence has_value returns true.
In this case T && value() && is called indeed.
f(std::move(optA.value())); // OPTION 2
T && value() && is not called here, because optA is not &&. So you get A& and cast it to A&& by std::move, then pass to f which presumably does nothing. optA wasn't changed and still reports that it contains value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With