GCC does not see function introduced from base class as ambiguous

104 views Asked by At

The following code

struct Foo{};
struct Bar{};

struct Base {
    Foo func1(const Foo , const Bar = Bar{}) const {
        return {};
    };
};

struct Derived : public Base {
    using Base::func1;
    Foo func1(const Foo ) const {
        return {};
    };
};

int main() {
    Foo foo;
    Derived der;
    der.func1(foo);
}

is rejected by ICX and clang, but accepted by GCC (up to 13.1). https://godbolt.org/z/4M3rrs3r4

I think GCC is wrong here. If the two func1s were non-members, GCC would reject the call as ambiguous.

Am I right?

2

There are 2 answers

0
Vlad from Moscow On

It is a bug of the compiler gcc.

From the C++ 20 (9.9 The using declaration)

15 [Note 6 : For the purpose of forming a set of candidates during overload resolution, the functions that are introduced by a using-declaration into a derived class are treated as though they were members of the derived class (11.8). In particular, the implicit object parameter is treated as if it were a reference to the derived class rather than to the base class (12.4.2). This has no effect on the type of the function, and in all other respects the function remains a member of the base class. — end note]

and (9.3.4.7 Default arguments)

  1. ... When a declaration of a function is introduced by way of a using-declaration (9.9), any default argument information associated with the declaration is made known as well.

So for the overload resolution the set of function candidates in the class Derived consists of two functions

Foo func1(const Foo , const Bar = Bar{}) const {
    return {};
}

and

Foo func1(const Foo ) const {
    return {};
}

And such a call

der.func1(foo);

in this case is ambiguous. Either function can be called.

0
Andrew Pinski On

It is a bug that was introduced with GCC 7: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82894