简体   繁体   中英

Assigning double to const int& vs int to const int&

I am trying to understand constant reference in C++ and I stumbled across this problem:

When I assign double to a const int& and then change the value of the referencing double, the value of my int reference stays constant.

    double i = 10;
    const int &ref = i;    
    i = 20;

    cout << "i: " << i << endl;      // i = 20
    cout << "&ref: " << ref << endl; // ref = 10

Whereas while assigning int, the value gets changed.

    int i = 10;
    const int &ref = i;    
    i = 20;

    cout << "i: " << i << endl;      // i = 20
    cout << "&ref: " << ref << endl; // ref = 20

What is the reason for this behaviour? My guess is that when assigning double, the implicit conversion to int creates a new object and its reference is then being assigned, however I can't find it written down anywhere.

Even though it looks like, ref isn't a reference to i .

double i = 10;
const int &ref = i;   // ***
i = 20;

A reference to an int cannot refer to a double . Therefore, in the marked line, a conversion from a double to an int takes place and the result of conversion is a temporary rvalue. Normaly, they are destroyed when the full expression they were created in ends. But there's a rule in C++ that allows extending the lifetime of a temporary when it is bound to a reference to const . It is extended until the reference dies. For that, the compiler actually allocates some memory for it behind the scenes.

The assignment modifies the original object i , the unnamed temporary stays intact.

When you convert the double to an int , the result is an rvalue of type int . This temporary value is bound to a constant reference variable, and thus the lifetime of the temporary value is extended to that of the reference variable. Changing the original double has no effect on that.

The compiler can help you a lot only if you remove const from both declarations and attempt to compile the code snippets:

double i = 10;
/*const*/ int &ref = i;    //ERROR - WHY?

This code will give compilation error! Why?

But this code:

int i = 10;
/*const*/ int &ref = i;   //NO ERROR

will compile fine.

If the first code compiles fine when there is const , why doesn't it compile now (when const is not there)? What is going on under the hood?

Well, the reason is, actually int& is a reference type which can refer to an object of type int only, not double , so a temporary object of type int is created out of the expression i (which is double ), but the temporary object cannot bind to int& , so it gives compilation error , but as soon as you put const there, it compiles fine, because a temporary object of type int can bind to const int& .

No such thing happens in the second code — no temporary object is created. So when you set i to 20 , the ref also changes in the second case (as it refers to i ) but in the first case, when you set i to 20 , the ref does not change because ref does not refer to i anymore — it rather refers to the temporary object (which you're not changing!). That explains the behaviors of your code snippets.

Hope that helps.

double i = 10;
const int &ref = i; 

Depending on the compiler you are using this code, as is, could as well give a compilation error.

On a compiler where it throws an error, if you cast it to (int &) you would see undefined behavior, since you are reading an int from a double's location. On a compiler which accepts this line, my best guess is it is creating a temporary variable (an rvalue) and assigning to the int reference, and any changes to the original variable are not reflected in the reference.

For the reference to work make sure the source data type can be represented by destination data type.

You can think of an int as a class, and int(double); as a way of constructing an int from a double, you have a const reference to that int, which was constructed from a double.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM