Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why a const function cannot return a non-const reference to a member

28 views
Skip to first unread message

JiiPee

unread,
Jun 20, 2015, 6:54:36 AM6/20/15
to
I pretty much understand const correctness. But there is one thing I do
not understand 100%:

class A
{
public:
int& foo() const // does not compile, should be: const int& foo() const
{
return p_;
}
private:
int p_;
};

This does not compile because there foo should return a const reference:
const int& foo() const

But why? Because to my understanding a const function ( "...foo() const"
) means that the *function foo* promises not to change the data members
of the object. If I return a reference to a member then foo is not
changing the data members, right? Yes, the caller can change the private
member later on, but foo did not. What am I not understanding correctly?
Or is it that the definition of const function: "the function is not
changing the state of the object" is not accurate but should be like
"the function is not changing the state of the object AND also the
caller cannot change the state of the object with the return value"?

What is the real and full definition of "const member function"?
Obviously it is not "the *function* promises not to change the data
members of the object". It is confusing because it seems like most of
the web sites seem to define it wrongly like that.

Victor Bazarov

unread,
Jun 20, 2015, 7:42:10 AM6/20/15
to
It has nothing to do with what 'foo' does to the object. It is a side
effect of the fact that '*this' is constant *inside* that function.
Every part of '*this' is considered constant *inside* 'foo'. When you
try to return 'p_', it is constant, and the compiler would have to
convert a const lvalue to a non-const lvalue in order to bind the
reference (the return value) to it. *That* is prohibited.

You're free to return a non-const ref to anything else, for instance to
a static object defined inside 'foo'.

V
--
I do not respond to top-posted replies, please don't ask

JiiPee

unread,
Jun 20, 2015, 8:23:27 AM6/20/15
to
just to clarify,
"it" - are you refering here to the definition of the "const member
function"?

> It is a side effect of the fact that '*this' is constant *inside* that
> function. Every part of '*this' is considered constant *inside*
> 'foo'. When you try to return 'p_', it is constant, and the compiler
> would have to convert a const lvalue to a non-const lvalue in order to
> bind the reference (the return value) to it. *That* is prohibited.
>
>

ok, so we can think that p_ (after declaring the function as const
function) becomes like:
const int p_;
And then for example for:
int foo() const { return p_; }
it would mean that we are doing a copy for the return value:
int return = p_;
which works because const can be copied to an int.
But with reference return value it would be like:
int& return = p_;
which is not working because non-const ref cannot refer to a const. Right?

If I see it like this then its easy to understand....

JiiPee

unread,
Jun 20, 2015, 8:25:08 AM6/20/15
to
On 20/06/2015 13:23, JiiPee wrote:
>
> ok, so we can think that p_ (after declaring the function as const
> function) becomes like:
> const int p_;
> And then for example for:
> int foo() const { return p_; }
> it would mean that we are doing a copy for the return value:

> int return = p_;

well, better would be "returnValue = ..." not to confuse with the
keyword return, but am sure you got it :)

Victor Bazarov

unread,
Jun 20, 2015, 7:33:04 PM6/20/15
to
"It": your inability to return a ref to non-const part of a const object.

>> It is a side effect of the fact that '*this' is constant *inside* that
>> function. Every part of '*this' is considered constant *inside*
>> 'foo'. When you try to return 'p_', it is constant, and the compiler
>> would have to convert a const lvalue to a non-const lvalue in order to
>> bind the reference (the return value) to it. *That* is prohibited.
>>
>>
>
> ok, so we can think that p_ (after declaring the function as const
> function) becomes like:
> const int p_;

Exactly.

> And then for example for:
> int foo() const { return p_; }
> it would mean that we are doing a copy for the return value:
> int return = p_;

Yep.

> which works because const can be copied to an int.
> But with reference return value it would be like:
> int& return = p_;
> which is not working because non-const ref cannot refer to a const. Right?

Yep.

>
> If I see it like this then its easy to understand....

Precisely. Everything is easy if you just think about it.
0 new messages