3

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?

Pipo
  • 185
  • 8

1 Answers1

6

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.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • But, i know that only const lvalue reference can be bound to a temporary. Is there any rule that let a plain lvalue reference to be bound to a temporary, if its lifetime is extended? – Pipo Sep 06 '14 at 23:52
  • @Toccio: That's not true. Only const lvalue references (and rvalue references) may be bound to an object accessed through an rvalue expression. But `a` is an lvalue expression because it refers to an object's _name_. It doesn't really matter than the object the references refer to is a temporary. – Lightness Races in Orbit Sep 06 '14 at 23:53
  • One more questions: when i bind lvalue reference A to an other lvalue reference B that refer to C, what i'm really doing is binding A to C right? So, if B is an rvalue reference, and C is a temporary, is it like i bind A to C? – Pipo Sep 06 '14 at 23:58
  • @Toccio: Ehm I guess so; your question isn't too clear. – Lightness Races in Orbit Sep 07 '14 at 00:02
  • Mh, try this way: an int& can be bound to an int lvalue, to int& and to int&& that are lvalue (like the example in the first post). Change the value of an int& is like change the value of the object referenced by it.Calling this object O, if O is, in turn, a reference (rvalue or lvalue doesn't matter), the change to O will, in turn, be a change on the object referenced by O, and so on, until a reach a non-reference type. Is all of this right? – Pipo Sep 07 '14 at 00:11
  • You're still confused. You can't "change the value of an int&", and you can't bind a "int&" to an "int&" or a "int&&". You _are_ operating on, or binding to, "the object referenced by it". In a parallel universe you're correct because the end result is the same, but in our universe there is no "chaining" because there doesn't need to be! – Lightness Races in Orbit Sep 07 '14 at 00:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60765/discussion-between-toccio-and-lightness-races-in-orbit). – Pipo Sep 07 '14 at 00:20