Ambiguous string::operator= call for type with implicit conversion to int and string
c++, conversion-operator, implicit-conversion, overload-resolution, string
Solution
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.
Problem
Given the following program: ``` #include <iostream> #include <string> using namespace std; struct GenericType{ operator string(){ return "Hello World"; } operator int(){ return 111; } operator double(){ return 123.4; } }; int main(){ int i = GenericType(); string s = GenericType(); double d = GenericType(); cout << i << s << d << endl; i = GenericType(); s = GenericType(); //This is the troublesome line d = GenericType(); cout << i << s << d << endl; } ``` It compiles on Visual Studio 11, but not clang or gcc. It is having trouble because it wants to implicitly convert from a `GenericType` to an `int` to a `char` but it also could return a `string` and so there is an ambiguity (`operator=(char)` and `operator=(string)` both match `GenericType`). The copy constructor is just fine, however. My question is: How do I resolve this ambiguity without modifying the contents of main? What do I need to do to modify `GenericType` to handle this situation?