Search code examples
c++c++11overload-resolution

Overloading with “const” at end of function declaration


I have 3 attempts to overload function "begin()"

class Test
{
public:

    //case 1: compiler error
    int begin();
    const int begin();

    //case 2:compiler warning: type qualifiers ignored on function return type
    int begin();
    const int begin() const;

    //case 3: ok
    int begin();
    int begin() const;
};

For the two cases that build successfully, how does the compiler choose which overload is called for begin()?


Solution

  • Member functions have an implicit argument which is the instance of the class itself. So you can think your functions as really looking like:

    // 1) compile-error as const-qualifications on return doesn't distinguish
    //    the functions - you cannot overload on return type
    int begin(Test& );
    const int begin(Test& );
    
    // 2)
    int begin(Test& );
    const int begin(const Test& );
    
    // 3)
    int begin(Test& );
    int begin(const Test& );
    

    With the 2nd and 3rd cases, the const-qualification on the function is equivalent to that implicit argument being a reference-to-const. So when you have something like:

    Test{}.begin();
    

    That calls begin() using a reference to non-const Test as the implicit first argument. Both overloads of begin() are viable, both require no conversions, so the least cv-qualified reference is preferred, which is the non-const-qualified function.

    Instead, when you have:

    (const Test{}).begin();
    

    we're calling begin() with a reference to const Test. So the non-const-qualified function is not a viable candidate (you cannot pass a const-ref to a function expecting a non-const-ref), so the best viable candidate is the only viable candidate: int begin() const.