https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112099

            Bug ID: 112099
           Summary: GCC doesn't recognize matching friend operator!= to
                    resolve ambiguity in operator==
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: usaxena95 at gmail dot com
  Target Milestone: ---

https://godbolt.org/z/13T5vhETK
```cpp
struct S {
    operator int();
    friend bool operator==(const S &, int);
    friend bool operator!=(const S &, int);
};

struct A : S {};
struct B : S {};

bool x = A{} == B{}; // ambiguous!!
```

Adding a decl for `operator!=` to the **namespace scope** makes it work fine:
https://godbolt.org/z/zzGWxb9zG
```cpp
struct S {
    operator int();
    friend bool operator==(const S &, int);
    friend bool operator!=(const S &, int);
};

bool operator!=(const S &, int);

struct A : S {};
struct B : S {};

bool x = A{} == B{};
```

According to [P2468R2 - The Equality Operator You Are Looking
For](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html)

""" 
A non-template function or function template F named operator== is a rewrite
target with first operand o unless a search for the name operator!= in the
scope S from the instantiation context of the operator expression finds a
function or function template that would correspond ([basic.scope.scope]) to F
if its name were operator==, **where S is the scope of the class type of o if F
is a class member, and the namespace scope of which F is a member otherwise**.
A function template specialization named operator== is a rewrite target if its
function template is a rewrite target.
"""

It feels like for `friend` functions (which are class members), `S` is
namespace scope. A lookup in the namespace scope does not find a matching
`operator!=` unless declared outside the class scope.

The need to add a re-decl of the friend outside of class scope looks
unreasonable to me. This looks to me like an oversight in this paper OR this is
a compiler bug and namespace lookup should actually find the `friend operator!=
in class scope` and resolve the ambiguity.

Reply via email to