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?
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.