Why is the overloaded method with a const reference return not being called?

Consider the following piece of code:

#include <iostream>

using namespace std;

class A {
    private:
    int x;
    public:
    int& get_ref() {
        cerr << "non const" << endl;
        return x;
    }

    const int& get_ref() const {
        cerr << "const" << endl;
        return x;
    }
};

int main () {
    A a;
    a.get_ref() = 10;

    cout << a.get_ref() << endl;

    const int& y = a.get_ref();

    return 0;
}

      

I expect the second and third calls a.get_ref()

to trigger the second version of the method get_ref()

(and const

standard error output ). But it looks like the first version is always called. How can I implement two different "getters" and make sure the correct version is called based on the context? Ie at least for the third call

const int& y = a.get_ref();

      

second version running? (Not an elegant solution would be to use different names like get_ref

and get_const_ref

, but I'm trying to figure out if this can be avoided.)

+3


source to share


2 answers


Overload resolution does not depend on return values, but only on arguments, including the object to be called for the member function. a

is a non-constant object, then a a.get_ref()

non-constant function will always be called.

You can pass it in const

for the called version:

const_cast<const A&>(a).get_ref();

      




By the way: giving them different names is not a bad idea. This is why we are std :: cbegin and std :: cend in STL.

+5


source


Overload resolution only affects call arguments (including the implicit argument for this

). The expression a.get_ref()

must evaluate with the same overload regardless of what happens to its return value. This is fundamental in C ++ and there is nothing you can do about it.

If you want to call the const

-qualified version, use the const

-qualified object expression :



const int& y = const_cast<const A&>(a).get_ref();

      

0


source







All Articles