Search code examples
c++c++11language-lawyerdiagnosticsambiguous-call

Obviously ambiguous call does not cause a compilation error on GCC


I was surprised by the fact that GCC does not consider the call to foo() in the following program ambiguous:

#include <iostream>

struct B1 { bool foo(bool) { return true; } };
struct B2 { bool foo(bool) { return false; } };

struct C : public B1, public B2
{
    using B1::foo;
    using B2::foo;
};

int main()
{
    C c;

    // Compiles and prints `true` on GCC 4.7.2 and GCC 4.8.0 (beta);
    // does not compile on Clang 3.2 and ICC 13.0.1;
    std::cout << std::boolalpha << c.foo(true);
}

The above function call compiles and returns true on GCC 4.7.2 and GCC 4.8.0 (beta), while it won't compile (as I would expect) on Clang 3.2 and ICC 13.0.1.

Is this a case of "no diagnostic required", or is it a bug in GCC? References to the C++11 Standard are encouraged.


Solution

  • §7.3.3/3:

    In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined. If such a using-declaration names a constructor, the nested-name-specifier shall name a direct base class of the class being defined; otherwise it introduces the set of declarations found by member name lookup (10.2, 3.4.3.1).

    ¶14:

    … [ Note: Two using-declarations may introduce functions with the same name and the same parameter types. If, for a call to an unqualified function name, function overload resolution selects the functions introduced by such using-declarations, the function call is ill-formed.

    ¶16:

    For the purpose of overload resolution, the functions which are introduced by a using-declaration into a derived class will be treated as though they were members of the derived class.

    So, the using declarations are legal, but the functions are peers in the same overload set, as you said, and the program is ill-formed.