I have a question about reference in C++.
this line int& refVal4 = 10;
is wrong,
but const int& refVal4 = 10;
is right.
So i am confused, who can help me clear this problem?
I have a question about reference in C++.
this line int& refVal4 = 10;
is wrong,
but const int& refVal4 = 10;
is right.
So i am confused, who can help me clear this problem?
In your code, int &
is a non-const lvalue reference. const int &
is a const lvalue reference.
The rules about reference binding are that a non-const lvalue reference may only bind to an lvalue expression. If you are unsure what an lvalue expression is, see this answer. 10
is a prvalue expression.
This rule does not reflect some underlying truth about the nature of the number ten or anything, as suggested in many comments. Rather, it is an arbitrary decision. To avoid the red herring of 10
(which is a non-const int
, by the way), we could instead consider;
int & y1 = atoi(6); // error
const int & y2 = atoi(6); // OK
int && y3 = atoi(6); // OK
++y3; // OK
In the cases y2
and y3
, the rules of reference binding are that a temporary object is created which is initialized from the value in the initializer. Then the reference binds to that temporary object (and the lifetime of that temporary object is extended to match the lifetime of the reference).
It is the same for binding to 10
: we do not bind to some platonic ideal or some fixed memory location that is preset to contain 10
. In fact we create a temporary int
whose value is 10, and bind to that. It is nonsense to talk about "changing the value of 10
".
As you can see from the y3
example, there is no technical reason why y1
could not work. In fact, disallowing y1
was a design decision made by Bjarne Stroustrup. He felt that allowing this would lead to coders making more mistakes. For example:
void increment(int &x) { ++x; }
int main()
{
long y = 123;
increment(y);
}
If the non-const lvalue binding were allowed then this code would compile successfully and have no effect on y
. x
would bind to a temporary int. Bjarne felt it would be better if this code gave a compilation error because the programmer usually would not want this to happen.
int& refVal4 = 10;
Here refVal4 is a reference to a non-const. Hence, the user can do something like refVal4 = 20.
Now, if refVal4 is pointing to a r-value (10) then the refVal = 20;
(which is same as saying 10=20)
does not make sense and is invalid. However, const int& refVal4 = 10;
is perfectly valid as it is a reference to a constant and hence one cannot modify by saying refVal = 20;
and results in compile time error. So, the compiler allows a reference to const to refer to r-values (and l-values) as the user is only allowed to read - (int val = refVal4)
and not change the referenced value.