Search code examples
c++language-lawyeroverloadingref-qualifierfunction-qualifier

Overloading a parent member function without ref-qualifier with a child member function with ref-qualifier in C++


In C++ one cannot overload in one class a member function with ref-qualifier with a member function without ref-qualifier. But at the same time it is possible to inherit one member function from a parent class and overload it in a child class as in the example:

struct A {
    void f() {}
    //void f() & {} //overload error everywhere
};

struct B : A {
    using A::f;
    void f() & {} //ok everywhere
};

int main() {
    B b;
    b.f(); //ok in GCC only
}

Only during the invocation of f, Clang complains that call to member function 'f' is ambiguous. But GCC accepts the program without any error, demo: https://gcc.godbolt.org/z/5zzbWcs97

Which compiler is right here?


Solution

  • GCC is correct to accept this, but the situation changed recently. The current phrasing is that a using-declaration in a class ignores (base-class) declarations that would be ambiguous (in a sense that is more strict than for overload resolution, partly because there is no argument list yet) with other declarations in the class. void() and void() & members are ambiguous in this sense, so b.f finds only B’s f and the call is valid.

    In previous (as of this writing, that means “published”) versions of the standard, both functions would be made available because the & distinguished them (in a sense that is even stricter), which would not only render the call ambiguous (as Clang says) but be ill-formed outright because the base- and derived-class functions were checked for overload compatibility which they lack.