<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/70210>70210</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Clang doesn't recognize friend operator!= to resolve ambiguity in operator==
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang,
c++20
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
usx95
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
usx95
</td>
</tr>
</table>
<pre>
https://godbolt.org/z/abdvexjo7
```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/ndrEeY68G
```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 member), `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 outisde class scope looks unreasonable to me. This looks to me as an oversight to me while considering this.
That said, I think it should be reasonable for clang to accept `friend operator!= in class scope` as an extension.
cc: @zygoloid @AaronBallman
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVk1v4zYT_jX0ZRBDor_igw92snqxwAu0aPayR4ocWdxQHJWk4iS_vhhKSRxvul3soShgKMp8aZ5nPkgVoz16xJ1YHYSUQ3zcroSUYnU7U0NqKeyyaFaTedq1KfVRLPZCVkJWRzI1uTSncBSyehayUrV5wMdvtBHFrSj2Yl2MP933oySmMOgEdyA2h1ECAEA9BpUogPVJyGsht2Jxpm6CRW-gJnKvpmJxyz95rcnHHFCuhbwZI5y5f-gry5_xFZvbt_fz7PcgFvsJw5nNpD18rB2fOY9HEItb2I8GMCKBw6s9jOyC6mp7HGiInK8sLyg9j7o3xvojKDCoHTQUQKyLC7TrAhJBahGE3Au596rD2CuNEDX1OAqhU_cYwSY4UbiHxnpkMP9Udm_CJ_y6vv7ff6bsf-f-q5X_pSj_Ys_8qDm0ppD7IxGI1eF3uVxf_yHhCr60CJ_-HJSz6Ql-eynGVxpgHxD-T3TPXhUFsWK077vgdDrNqUd_FZOZWuFb0qWQVdRSssGR27YypKOQVa96DPwii6ztOYsg523qHJN2njB48lcJu96phNAMXidLHii8vb9qK-BGNhcNAjaCgoCnYBNCUuGICU42tdDYENNo7Q0QDN5hZOOIKug2Dw8PCUe9KDhYn1V5XuAOmkBdFlgfk_LJqpyaJp_wMQE1Wfna5PjYB4yRTRrrDX_zx9BSq3gOB2dAUwgYe_IGeFBWh1pFq-c5k_GZS7TlEldgG7ApjhBOGPC76bmZdsCpZe0ds_UGbMpbOxUjpKdRQhy0GmkdNR12NQaOxUS-UHa2Udjt1FrdvviNHkCpxXCycVo5c9h_gD32qK1y9nnk9KdrPEH_PuAHxvPzpvucoEF0EZy9x5cVOq4QXp0vASPzP6JSAS-o2GZm18Ude9h4SQgjdUT3Q__SSZeMGcIInlJuEGZMJd3yDH64zqfW5Z2vAtMzpGgNnlVv_Ow5TB55j2i4UZQxmZOrfGpMZZ-2Jg3JRvMuTs49wuADqkhe1Q45Sodz-NLaOKmzBFQE5YEeMER7bNMkPbXWIc8HpxnyRmptnMP7BFWCqKxhLj-zgb_n8yi2eRBqhLPPc5m0U-NqU1pjn97K9sH0nqFhAscs8TGh57GciNKad7FYFs9PR3JkDb_vVSB_UM51ysPM7BZmu9iqGe7K9fZaLuWyLGftrrlembKQZaOabbEx2-3GGL1Zq3W5kuVqqWZ2Jwu5KAu5KpdFUZZzs21qI1cKV0Wz2dQolgV2yrq5cw8dr9WZjXHA3aaQZTFzqkYXp5taBs43NXnD_wl5EPIgi-nuFnYc4aoejlEsC2djim8xk00OdzeZOe45L-QmQUBNR2-f35rgPYGJIGAk94DT1YSPDesvxnI2BHd5T7SpHeq5pk7IipOY_lz1gb6hTkJWGSUfDxnoXwEAAP__UWJO1A">