I've read all the major questions on SO about different value categories but still don't clearly understand the difference between, in this case, xvalues vs prvalues.
I know that, like all glvalues, xvalues can have their dynamic type different from the static one, but e.g. in case of literal vs std::move
from literal I can't find 'real' behavioral differences (maybe apart from those that are formally based on what's xvalue and what's prvalue, like which constructor will get called in MyClass(std::move(5))
; but it doesn't seem that important in case of literals since their values won't be used anyway.
What is the actual 'benefit' I can get from calling std::move
on a literal?
What is the actual 'benefit' I can get from calling
std::move
on a literal?
None. A (non-string) literal is a prvalue, which is an rvalue. Calling std::move()
will give you an xvalue, but that is still an rvalue. There's no way to overload on the difference between xvalue and prvalue - you can only overload on the difference between lvalue and rvalue - so there's no subsequent difference.
However, if we generalize to calling std::move
on a prvalue, there is one big anti-benefit: you lose temporary lifetime extension in some places where you might need it. Consider:
SomeContainer foo();
for (auto&& elem : foo()) { ... }
That works fine. You can iterate over a prvalue like that. However, this does not work at all:
SomeContainer foo();
for (auto&& elem : std::move(foo())) { ... }
We still have an rvalue of type SomeContainer
, but now our temporary is bound to the reference parameter of move()
so it goes out of scope before the body of the for
loop is entered. Oops.