c++referencepolymorphismoverloadingconst-reference

Why the overloaded method with const reference return value is not 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 to a.get_ref() to run the second version of get_ref() method (and output const on the standard error). But it looks like always the first version is called. How can I implement two different 'getter's and make sure that the proper version is called based on the context? I.e., at least for the third call

const int& y = a.get_ref();

the second version is executed? (A non-elegant solution would be to use different names e.g. get_ref and get_const_ref but I am trying to see if that can be avoided.)


Solution

  • Overload resolution doesn't depend on return values, but only arguments, including the object to be called on for member function. a is a non-const object, then for a.get_ref(), the non-const member function will always be called.

    You can cast it to const for the const version to be called:

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

    BTW: Giving them different names is not a bad idea. That's why we have std::cbegin and std::cend in STL.