I believe that gcc and clang are correct.
There are two operator=
overloads in play:
string& operator=(string const& str); // (1)
string& operator=(char ch); // (2)
Both of these operator=
overloads require a user-defined conversion from your argument of type GenericType
. (1) requires the use of the conversion to string
. (2) requires the use of the conversion to int
, followed by a standard conversion to char
.
The important thing is that both overloads require a user-defined conversion. To determine whether one of these conversions is better than the other, we can look to the overload resolution rules, specifically the following rule from C++11 §13.3.3.2/3 (reformatted for clarity):
User-defined conversion sequence U1
is a better conversion sequence than another user-defined conversion sequence U2
if
they contain the same user-defined conversion function or constructor or aggregate initialization and
the second standard conversion sequence of U1
is better than the second standard conversion sequence of U2
.
Note that an and joins the two parts of the rule, so both parts must be satisfied. The first part of the rule is not satisfied: the two user-defined conversion sequences use different user-defined conversion functions.
Therefore, neither conversion is better, and the call is ambiguous.
[I don't have a good suggestion on how to fix the problem without changing the definition of main()
. Implicit conversions are usually not a good idea; they are sometimes very useful, but more frequently they are likely to cause overload ambiguities or other weird overloading behavior.]
There was a gcc bug report in which this problem was described, and resolved as by design: compiler incorrectly diagnoses ambigous operator overload.