7

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?

2
  • Huuuh, curious. It looks like they use different versions of standard for this. Commented Nov 18, 2021 at 7:14
  • I would say gcc-bug. (msvc rejects it as clang Demo). Commented Nov 18, 2021 at 13:14

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. Could you please add a link to this point in the standard?
So, which compiler is actually wrong here in the end? I'd like to report this bug to one of them, so that they act the same
@dragonroot: GCC is correct. The committee doesn’t usually issue the Technical Corrigenda needed to formally make this true for C++20, but I’d expect it to be (eventually) implemented for all language modes back to C++11. Clang isn’t right in any language version because it rejects only the call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.