I can do const A& a = A()
and A&& a = A()
, but why cannot I do A& a = A()
?

- 688
- 1
- 6
- 17
-
Due to a perhaps unfortunate decision back in the day, I think maybe you are confusing forwarding references, which appear only in templates, with rvalue references. They share the same `&&` syntax, but they are completely different things. The question is too vague. Post a [MCVE] incorporating `A&& a = A()`. – Jive Dadson Mar 16 '18 at 07:37
-
3@JiveDadson The question seems pretty clearly to me to be about rvalue references, not forwarding references. I looked back to see if it was perhaps unclear before the edit, but no, it was pretty clear in its initial version as well. – Mar 18 '18 at 13:59
-
@hvd +1. I am very confused about why this question is considered as vague. If anyone thinks it is vague, can you please let me know why and where? Otherwise it is very confusing to just put it on hold as unclear but not telling where the unclear is. – Eric Mar 19 '18 at 07:14
-
tempted to close as dupe: https://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object – bolov Mar 19 '18 at 10:12
-
1The rationale is that it rarely makes sense to mutate a temporary, and any attempt to do so is likely to be a programming error rather than a deliberate decision. While you do sometimes want to mutate a temporary, it's often for an entirely different reason from that of mutating an lvalue (rvalue references exist to accommodate these cases). – n. m. could be an AI Mar 19 '18 at 10:33
-
1@n.m. I think this should be an answer. – bolov Mar 19 '18 at 10:34
3 Answers
The rationale is that it rarely makes sense to mutate a temporary. Any attempt to do so is likely to be a programming error rather than a deliberate decision.
The prototypical example is as follows. Assume binding to non-const reference is allowed.
void foo(int& x, int& y); // sets x and y
int xx, yy;
foo(xx, yy); // xx and yy are set
// now make a small change...
void foo(long& x, long& y); // upgrade
int xx, yy; // forgot to change here
foo(xx, yy); // silently breaks
While one does sometimes want to mutate a temporary, it's often for an entirely different reason from that of mutating an lvalue. Rvalue references were invented to accommodate these cases.

- 112,515
- 14
- 128
- 243
-
I tried your example, and the compilation failed with the error `invalid initialization of non-const reference of type ‘long int&’ from an rvalue of type ‘long int`, I understand that that is because a temporary variable was created when I did the second `foo(xx, yy);`. But I am not quite sure about what you mean for `// silently breaks`, can you please elaborate a bit? Thanks! – Eric Mar 20 '18 at 02:17
-
@Eric Have you read what I have written? *Assume binding to non-const reference is allowed.*. – n. m. could be an AI Mar 20 '18 at 04:30
-
Sorry, I misunderstood your point. Now I see the point that if binding to non-const reference was allowed, the functionality of `foo` will be silently broken. Thanks! – Eric Mar 20 '18 at 07:50
By "initialising an lvalue reference" you refer to defining the lavalue which the reference is referring to from then on.
So the lvalue-reference will propagate any access to the rvalue "initialisation".
I.e. you would attempt to access an rvalue-expression like an lvalue.
It is not possible in all cases to access an rvalue like an lvalue.
That is why.

- 26,130
- 9
- 42
- 54
-
I don't think that's what he's getting at. The question is too vague to tell. – Jive Dadson Mar 16 '18 at 07:38
-
@JiveDadson You might be right. I got the impression that the whole (vague) question is simply based on a misconception about what a reference is. It seems to me that the whole "it is the thing and the whole of the thing itself" idea did not get across. I felt that while the question is vague, the problem is clear. – Yunnosch Mar 16 '18 at 07:41
An rvalue is a temporary - it's going to die soon. Creating a lvalue reference to such an object would be a recipe for disaster since the reference would become a dangling reference to a dead object very quickly.

- 30,449
- 3
- 47
- 70
-
1
-
@songyuanyao binding a reference to a prvalue extends lifetime of the temporary materialized from the prvalue – M.M Mar 19 '18 at 10:07