3
votes

I have tried to compile:

int &&a=3;
int &b=a;

And it work. I know that "a" is an lvalue, but why i can bind an "rvalue reference to int" to an "lvalue reference to int (not to an rvalue reference to int)"? This way, i can change the value of the temporary, 3:

b=5 //changing the value of the temporary bound to the rvalue reference

This tecnique is used from std::forward, so i suppose it is a standard behavior. Is an rvalue reference to int considered as a simple int lvalue storing a temporary? If not, how do you explain the binding?

1

1 Answers

6
votes

References don't bind to other references; they bind to objects.

When you initialise a from 3, you create a new, temporary int object whose lifetime is extended. b is simply another reference to that object.

Note that a is an lvalue, because it is an expression naming an object, even though it has type "rvalue-reference to int"! Be careful not to confuse types with value categories, here: types relate to objects, but value categories relate to expressions (even if those expressions name or otherwise evaluate to some object).

These confusing rules all fit in together quite neatly when you think about it: for the original reference to have been valid, the object's lifetime must have been extended, so b's initialisation is safe.