Reputation: 17183
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?
Upvotes: 1
Views: 58
Reputation: 141554
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
.
Upvotes: 1
Reputation: 17704
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.
Upvotes: 4