Ambiguity error accessing equality comparison operator in G++

Viewed 101

In case of multiple inheritance if all parent classes have their own equality comparison operator ==, and the child class has a (friend) function operator ==, as in the example:

struct A {
    bool operator ==(const A&) const = default;
};

struct B {
    bool operator ==(const B&) const = default;
};

struct C : A, B {};

constexpr bool operator ==(const C&, const C&) { return true; }

static_assert( C{} == C{} );

GCC prints the following error about ambiguity in an attempt to compare child objects:

 error: request for member 'operator==' is ambiguous
   13 | static_assert( C{} == C{} );
 note: candidates are: 'bool B::operator==(const B&) const'
 note:                 'bool A::operator==(const A&) const'

Demo: https://gcc.godbolt.org/z/W3qer376d

This error looks surprising, since operator ==(const C&, const C&) shall be preferred as the most suitable to the actual arguments. Is it simply a defect in GCC?

1 Answers

Indeed the global operator operator==(const C&, const C&) has priority. However the compiler "want to know" all the possibilities in order to decide: In other words: as soon as you try to use the operator== the compiler requires you to have no ambiguities, even if the required alternative is not between the ambiguous one.


struct C : A, B { using A::operator==; }; 

This resolves the ambiguity and allows you to use the global operator==

https://onlinegdb.com/nxMjPN4NC

#include <iostream>

struct A {
    bool operator ==(const A&) const { std::cout << "A" << std::endl; return true; };
};

struct B {
    bool operator ==(const B&) const { std::cout << "B" << std::endl; return true; };
};

struct C : A, B 
{
    //using A::operator==; // Uncomment this to make it work.
};

bool operator ==(const C&, const C&) { std::cout << "C" << std::endl; return true; }

int main()
{
    C c1, c2;
    
    c1==c2;

    return 0;
}

Result (when resolved):

C

Related