简体   繁体   中英

Why can I assign the return value of a function that returns `const T&`, to a `T` variable but not to a `T&` variable?

I have the following function. It returns of course a const reference.

const Something& getThing() {
    // 'data' is an array of pointers to Something
    const Something& item = *data[someIndex];
    return item;
}

This, obviously, compiles:

const Something& thing = getThing();

But for some reason, this compiles too:

const Something thing = getThing();

And even this compiles:

Something thing = getThing();

But this won't compile:

Something& thing = getThing();

Gives the following error:

Invalid initialization of reference of type 'Something&' from expression of type 'const Something'

I wouldn't expect Something& thing = getThing() to compile (since that would be converting a const to a non- const ). But I'd like to understand why const Something thing = getThing() and Something thing = getThing() compile. What are the technical reasons for this behavior?

The key points are two fold: first, you are returning a const reference, so the user of the function should not be able to change the original variable. This is why you cannot assign the result of the function call into a regular reference; regular references would not protect the const nature of the return and allow modification of the variable. Second, when you assign a const ref (or any ref) to a regular (non-ref) variable, a copy actually gets made. Since you are making a copy in those cases, you do not need a const copy of the object. If you were to modify the object, you would only be modifying the copy, and the original object's constness is preserved, which is the requirement.

This one:

Something thing = getThing() ;

means to create a new thing called thing which is copied from what is returned by getThing . So it doesn't matter whether the thing returned is const or not, because we are making a new object. You can always make a new non-const object by copying from some other data.

It is just the same as AlexD says in comments:

const double pi = 3.14;
double x = pi;    // OK! New variable copied from pi
x = x + 1;        // changes x, does not change pi

Similarly with const Something thing , we are making a new object which happens to be const .

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