Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot initialize non-const reference from convertible type

I cannot initialize a non-const reference to type T1 from a convertible type T2. However, I can with a const reference.

long l;
const long long &const_ref = l; // fine
long long &ref = l;             // error: invalid initialization of reference of
                                // type 'long long int&' from expression of type
                                // 'long int'

Most problems I encountered were related to r-values that cannot be assigned to a non-const reference. This is not the case here -- can someone explain? Thanks.

like image 842
Julien-L Avatar asked Oct 30 '25 21:10

Julien-L


2 Answers

An integer promotion results in an rvalue. long can be promoted to a long long, and then it gets bound to a const reference. Just as if you had done:

typedef long long type;
const type& x = type(l); // temporary!

Contrarily an rvalue, as you know, cannot be bound to a non-const reference. (After all, there is no actual long long to refer to.)

like image 144
GManNickG Avatar answered Nov 01 '25 10:11

GManNickG


long long is not necessarily sized equal to long and may even use an entire different internal representation. Therefor you cannot bind a non-const reference to long to an object of type long long or the other way around. The Standard forbids it, and your compiler is correct to not allow it.

You can wonder the same way about the following code snippet:

long a = 0; 
long long b = 0;

a = b; // works!

long *pa = 0;
long long *pb = pa;

The last initialization won't work. Just because a type is convertible to another one, doesn't mean another type that compounds one of them is convertible to a third type that compounds the other one. Likewise, for the following case

struct A { long i; };
struct B { long long i; };

A a;
B b = a; // fail!

In this case A and B each compound the type long and long long respectively, much like long& and long long& compound these types. However they won't be convertible into each other just because of that fact. Other rules happen to apply.

If the reference is to const, a temporary object is created that has the correct type, and the reference is then bound to that object.

like image 28
Johannes Schaub - litb Avatar answered Nov 01 '25 12:11

Johannes Schaub - litb