Search code examples
c++language-lawyeroverload-resolution

Overload resolution between constructor and inherited constructor in C++ - which compiler is correct?


In the following program struct B inherits B(int) deleted constructor from its base A, and also defines additional constructor B(int&&). Then an object of B is created with B b(1):

struct A {
    A() {}
    A(int) = delete;
};

struct B : A {
    using A::A;
    B(int&&) {}
};

int main() {
    B b(1);
}

If both constructors B(int) and B(int&&) had been defined directly in B the result would have been the ambiguity of constructor selection. And in this example, GCC prints a

call of overloaded 'B(int)' is ambiguous`

error as well.

But Clang prefers the constructor declared in B over the one inherited from A. Demo: https://gcc.godbolt.org/z/dnErEenE5

Which compiler is right here?


Solution

  • GCC is correct here: there is a tiebreaker that prefers direct over inherited constructors ([over.match.best.general]/2.7), but it applies only if they have the same parameter types (ignoring those whose default arguments are being used).