1

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?

ledonter
  • 1,269
  • 9
  • 27

1 Answers1

2

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.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • By the way, why wasn't `std::move` implemented as a cast? Since it actually is an unconditional cast to rvalue. I know it actually is implemented via `static_cast` but making it itself a separate kind of cast would help to eliminate issues you mentioned. – ledonter Jul 19 '17 at 13:37
  • Not all literals are prvalues, even if we ignore user-defined literals. – T.C. Jul 19 '17 at 13:39
  • @ledonter That solves a problem that only exists if you chose to write code that doesn't have any benefit. A simpler solution would be to just not write `move()` there. – Barry Jul 19 '17 at 14:11
  • @T.C. Edited :) – Barry Jul 19 '17 at 14:11