This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
Consider:
struct B1 {
bool operator==(B1 const&) const;
};
struct B2 {
bool operator==(B2 const&) const;
};
struct D: B1, B2 {} d;
bool operator==(D const&, D const&);
auto r = d == d; // ambiguous?
There is implementation divergence in handling this example; some implementations select the non-member operator, others diagnose an ambiguous lookup.
Member name lookup for operator== is ambiguous, making the program ill-formed per 6.5.2 [class.member.lookup] paragraph 6:
The result of the search is the declaration set of S(N, T). If it is an invalid set, the program is ill-formed.
There is no provision for simply failing if the lookup is invoked as part of some larger lookup, as in the case of a lookup for an overloaded operator (12.2.2.3 [over.match.oper] paragraph 3):
For a unary operator @ with an operand of type cv1 T1, and for a binary operator @ with a left operand of type cv1 T1 and a right operand of type cv2 T2, four sets of candidate functions, designated member candidates, non-member candidates, built-in candidates, and rewritten candidates, are constructed as follows:
- If T1 is a complete class type or a class currently being defined, the set of member candidates is the result of a search for operator@ in the scope of T1; otherwise, ....
- For the operators =, [], or ->, the set of non-member candidates is empty; otherwise, it includes the result of unqualified lookup for operator@ in the rewritten function call (6.5.3 [basic.lookup.unqual], 6.5.4 [basic.lookup.argdep]), ignoring all member functions. ...
- For the operator ,, the unary operator &, or the operator ->, the built-in candidates set is empty. For all other operators, the built-in candidates include all of the candidate operator functions defined in 12.5 [over.built] that ...
- The rewritten candidate set is determined as follows: ...
It is unclear whether that is intended or desirable.
Suggested resolution:
Change in 6.5.2 [class.member.lookup] paragraph 6 as follows:
The result of the search isIf the declaration set of S(N, T). If itisaninvalidset,the program is ill-formedthe result of the search is an empty set; otherwise, the result is that set.
Rationale (CWG 2023-06-17)
Changing the lookup rules to yield an empty set has undesirable effects on non-operator lookup, where fall-back to non-member lookup is actually desired. The intended outcome for the example is as specified (i.e. the program is ill-formed). The example can be addressed by making operator== a member of D.