17

For some reason I didn't manage to find this exact question. Why is it allowed to bind an rvalue to const lvalue reference, although it is impossible to to the same without the const?

I do understand that the lifetime of the rvalue gets an extension somehow (in the first case) , but if so, why would the compiler disallow changing that 'rvalue', which is not really a temporary object anymore.

For example, consider the following code:

int main(){
   int &i=3; //produces error
   const int&j =3; //compiles
   return 1;
}
Eliran Abdoo
  • 611
  • 6
  • 17

3 Answers3

6

You may find the following article useful:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

I might be entirely wrong here, but this is how I rationalise it. An rvalue is constant, it cannot be changed. you cannot change the integer 5, fact. So when you bind the references the lvalue will have to be const. Otherwise your compiler will throw an error:

obj & a1 = bar();

invalid initialization of non-const reference of type ‘obj&’ from an rvalue of type ‘obj’

using g++

The only way to safely bind an rvalue to an lvalue is either by marking the lvalue as const, or using a mutable rvalue reference && (introduced in C++11 believe?)

struct obj {
};

obj bar() {
    obj x;
    return x;
}

int main() {
const obj & a1 = bar();
obj && a2 = bar();
return 0;
};
TomJ
  • 424
  • 3
  • 14
  • 1
    I understand your way of thinking, but after binding the rvalue into an lvalue, your'e practically giving it a name, and extending its lifetime beyond the current line. And lets put the rvalue reference out of the equation for now, I'm talking strictly about the rvalue to const lvalue ref thing. So my question remains the same, why does the requirement of 'const lvalue ref' holds, why can't just 'lvalue ref' suffice? – Eliran Abdoo Nov 29 '16 at 20:21
2

If you're asking about

void f(const int&);
f(1);

versus

void g(int&);
g(1);

the answer is to think about what happens if g looks like this:

void g(int& r) {
    ++r;
}
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • 1
    Perhaps a simpler case, `int main(){ int &i=3; //produces error const int&j =3; //compiles return 1; }` – Eliran Abdoo Nov 29 '16 at 20:16
  • @GoldenSpecOps - if you add `++i;` after the initialization you'll see why it's not allowed; if it started out `int j = 1; int&i = j; ++i;` it would be okay. – Pete Becker Nov 29 '16 at 20:53
0

The name r-value comes from the right-value: which (roughly) means things that are on the right side of a x=y kind of statement. It is like: it can be read from, but it may not be suitable to be written on. For example a numeric literal can be on the right side (a=3) but it does not make sense to be on the left side (3=a).

With this reasoning, it looks logical to me why it is allowed to make const l-value references to r-values but not allowed to make non-const references.