1

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?

BlackMamba
  • 10,054
  • 7
  • 44
  • 67
  • 6
    [*GotW #88: A Candidate For the “Most Important `const`”*](http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/) – BoBTFish Mar 07 '16 at 09:36
  • '10' in your example is const, a constant int of value 10. You then have to use a reference to const. – Jojje Mar 07 '16 at 09:38
  • http://stackoverflow.com/questions/7420780/what-is-a-constant-reference-not-a-reference-to-a-constant – abasu Mar 07 '16 at 09:38
  • 1
    You can't bind a (non-const) reference to an *rvalue*. – Some programmer dude Mar 07 '16 at 09:39
  • 2
    Because 10 is constant. Can you change value of 10 to 5 so that numbers becomes 0 1 2 3 4 5 6 7 8 9 5 11 12 ... ? – Muhammet Ali Asan Mar 07 '16 at 09:39
  • @JoachimPileborg I am confused about `rvalue` and `lvalue`, could you give me a explantion? – BlackMamba Mar 07 '16 at 09:42
  • Generally speaking (and very simplified) an *lvalue* can be on the *left* hand side of an assignment, and an *rvalue* can be on the *right* hand side. For more details please use your favorite search engine. – Some programmer dude Mar 07 '16 at 09:44
  • What is "this problem"? Could you be more specific about what you don't understand? – juanchopanza Mar 07 '16 at 10:24
  • @Jojje `10` is not `const`. The actual reason has nothing to do with anything like that. – M.M Mar 07 '16 at 11:11
  • @MuhammetAliAsan `10` is not `const`. Consider `int&& r = 10; r = 5;` That compiles and is correct. Did the numbers become 0 1 2 3 4 5 6 7 8 9 5 11 12 ? – M.M Mar 07 '16 at 11:18

2 Answers2

1

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.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
0

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.

Vishal
  • 158
  • 6