https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118394
Bug ID: 118394
Summary: Ambiguous usage of comparison operator caused by
multiple overloaded type conversion operator is not
identified
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: wangbopku15 at gmail dot com
Target Milestone: ---
The following code is accepted by GCC:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
#include<iostream>
struct operand
{
int x;
operator int (){return x;};
operator bool() {return true;};
operator char() {return 'c';};
};
bool bar (operand i, operand j)
{
bool tst = (i == j);
return tst;
}
int main(){
operand o1{1}, o2{0};
std::cout<<bar(o1, o2);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
The '(i==j)' expression seems questionable here as all of the three overloaded
type conversions can be chosen, which leads to ambiguous results (the result
would be '0' if 'operator int' is chosen and '1' if the other two is chosen).
Also note that GCC outputs '0' for the code above, but outputs '1' if 'operator
int' also returns a constant, which reveals that the compiler will think the
two operands are equal only if all of the three return values of the overloaded
type conversion operators are equal.
EDG, clang, and MSVC reject that:
https://godbolt.org/z/dnxdxdjEr
The diagnostic of clang:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
<source>:12:17: error: use of overloaded operator '==' is ambiguous (with
operand types 'operand' and 'operand')
12 | bool tst = (i == j);
| ~ ^ ~
<source>:12:17: note: because of ambiguity in conversion of 'operand' to
'float'
<source>:5:3: note: candidate function
5 | operator int (){return x;};
| ^
<source>:6:3: note: candidate function
6 | operator bool() {return true;};
| ^
<source>:7:3: note: candidate function
7 | operator char() {return 'c';};
| ^
<source>:12:17: note: because of ambiguity in conversion of 'operand' to
'float'
12 | bool tst = (i == j);
| ^
<source>:5:3: note: candidate function
5 | operator int (){return x;};
| ^
<source>:6:3: note: candidate function
6 | operator bool() {return true;};
| ^
<source>:7:3: note: candidate function
7 | operator char() {return 'c';};
| ^
<source>:12:17: note: built-in candidate operator==(float, float)
12 | bool tst = (i == j);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~