-5
#include <iostream>
using namespace std;

int&& move(int&& t) {
    return static_cast<int &&>(t);
}

int main() {
    move(5) = 10;//why error? 

    return 0;
}

Error

prog.cpp:9:13: error: using xvalue (rvalue reference) as lvalue

Here's the complete sample

I can not understand. Does not move function return a rvalue reference?

Scooter
  • 5,908
  • 8
  • 32
  • 59
user2178911
  • 381
  • 3
  • 7
  • You can't "move" an integer, even if you have an r-value reference to it. And you certainly can't assign *to* an integer literal. – Cameron Sep 28 '14 at 14:23
  • 1
    Suggesting to study all the terms in the error message – Marco A. Sep 28 '14 at 14:23
  • error:using xvalue(rvalue reference) as lvalue – user2178911 Sep 28 '14 at 14:24
  • @Cameron, I'm thinking the OP is expecting this to happen: http://coliru.stacked-crooked.com/a/ceaa01a9e7295059 – chris Sep 28 '14 at 14:24
  • 1
    Possible duplicate of: [What are rvalues, lvalues, xvalues, glvalues, and prvalues?](http://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues) – πάντα ῥεῖ Sep 28 '14 at 14:27
  • @user2178911 Take a serious look: `move(5) = 10;` What should this achieve actually? Telling `5` that it has to be `10` now, or the other way round?!? – πάντα ῥεῖ Sep 28 '14 at 14:30
  • 1
    @user2178911: Yes, your move function does return an rvalue reference. Even the error message confirms that. So what? Rvalue references are never allowed on the left-hand side of the built-in assignmenet operator. This is what the compiler is telling you. – AnT Sep 28 '14 at 14:43
  • @AndreyT http://ideone.com/Trw1AA – user2178911 Sep 29 '14 at 02:31
  • @user2178911: Well, *named* revalue reference is an lvalue. *Unnamed* rvalue reference is not an lvalue. In your original code you are using an unnamed rvalue referce, which is the key detail that makes it different. – AnT Sep 29 '14 at 03:31

1 Answers1

2

§ 3.10

From how I interpret the standard, lvalues, xvalues and prvalues are mutually exclusive.

Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue.

A literal such as 5 is a prvalue.

— A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. — end example ]

And in your "move" function, you get an xvalue because:

[ Example: The result of calling a function whose return type is an rvalue reference is an xvalue. — end example ]

As for why your assignment fails, see:

5 An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [ Example: a member function called for aobject (9.3) can modify the object. — end example ]

cppreference's page on assigment operators puts this in plainer language.

The direct assignment operator expects a modifiable lvalue as its left operand and an rvalue expression or a braced-init-list (since C++11) as its right operand, and returns an lvalue identifying the left operand after modification.

So finally:

       move(5) =      10
xvalue ^      prvalue ^

Reference: Value categories