Error: incorrect initialization of a non-constant reference of type 'int & from rvalue of type' int

Invalid form:

int &z = 12; 

The correct form:

 int y; int &r = y; 

Question :
Why is the first code wrong? What is the meaning of an "error in the header?

+51
c ++ pointers reference
Nov 28 '11 at 8:51
source share
5 answers

C ++ 03 3.10 / 1 says: "Each expression is either an lvalue or an rvalue value." It is important to remember that lvalueness compared to rvalueness is a property of expressions, not objects.

Lvalues ​​name objects that are stored outside of a single expression. For example, obj , *ptr , ptr[index] and ++x are all lvalues.

Rvalues ​​are temporary, which evaporate at the end of the full expression in which they live ("semicolon"). For example, 1729 , x + y , std::string("meow") and x++ are all r values.

The operator address requires its "operand must be lvalue". if we could take the address of one expression, the expression will be lvalue, otherwise it will be rvalue.

  &obj; // valid &12; //invalid 
+83
Nov 28 2018-11-11T00:
source share
 int &z = 12; 

On the right side, a temporary object of type int is created from the integral literal 12 , but the temporary cannot be tied to a non-constant reference. Hence the error. This is the same as:

 int &z = int(12); //still same error 

Why is a temporary creation created? Since the link must reference the object in memory and for the object to exist, it must be created first. Because the object is not specified, this is a temporary object. He has no name. From this explanation it became clear why the second case is in order.

A temporary object can be bound to a constant reference, which means you can do this:

 const int &z = 12; //ok 



C ++ 11 and Rvalue Reference:

For completeness, I would like to add that C ++ 11 introduced rvalue-reference, which can bind to a temporary object. So in C ++ 11 you can write this:

 int && z = 12; //C+11 only 

Note that there is && intead & . Also note that const no longer required even if the object to which z is attached is a temporary object created from integral literal 12 .

Since C ++ 11 introduced rvalue-reference, int& now called lvalue-reference.

+37
Nov 28 2018-11-11T00:
source share

12 is a compile-time constant that cannot be changed unlike data referenced by int& . What you can do is

 const int& z = 12; 
+6
Nov 28 '11 at 8:55
source share

Links are "hidden pointers" (non-zero) for things that can change (lvalues). You cannot determine their constant. This should be a "variable".

EDIT ::

I think about

 int &x = y; 

as almost equivalent

 int* __px = &y; #define x (*__px) 

where __px is the new name, and #define x only works inside the block containing the declaration x .

0
Nov 28 2018-11-11T00:
source share

Binding to a constant and a constant refers to different rules

These are the rules of the C ++ language:

  • an expression consisting of a literal number ( 12 ) is "rvalue"
  • it is not allowed to create a non-constant link with rvalue: int &ri = 12; poorly formed
  • allowed to create a constant link with rvalue: in this case, the compiler creates an unnamed object; this object will remain as long as the link itself exists.

You must understand that these are C ++ rules. They just are.

It's easy to come up with a different language, like C ++ ', with slightly different rules. In C ++, it would be allowed to create a non-constant link with rvalue. There is nothing inconsistent or impossible.

But this would allow some risky code where the programmer might not get what he intended, and C ++ designers rightly decided to avoid this risk.

0
Nov 29 2018-11-11T00:
source share



All Articles