I believe the GCC is wrong. In the book "C ++ Programming Language" Bjarne Straustup has a whole chapter on operator overloading. Section 11.4.1 in the first paragraph states the following:
"Assigning a value of type V to an object of class X is legal if there is an assignment operator X :: operator = (Z), so that V is Z or there is a single conversion of V to Z. Initialization is considered equivalent."
In your example, GCC takes "string s = GenericType ();" but rejects "s = GenericType ();" so it does not explicitly consider assignment in the same way as initialization. This was my first clue that something was wrong with the GCC.
GCC reports 3 candidates for converting GenericType to a string in an assignment, all in basic_string.h. One of them is the correct conversion, one of the messages that it reports is invalid, and the third causes ambiguity. This is an operator overload in basic_string.h that causes ambiguity:
/** * @brief Set value to string of length 1. * @param c Source character. * * Assigning to a character makes this string length 1 and * (*this)[0] == @a c. */ basic_string& operator=(_CharT __c) { this->assign(1, __c); return *this; }
This is not a valid conversion because it accepts an operand that does not match the type of object that was passed to it. In no case should you assign a char attempt, so this conversion should not be a candidate for all the much smaller ones, which causes ambiguity. GCC seems to mix the type of the template with the type of the operand in its member.
EDIT: I did not know that assigning an integer to a string was actually legal, since the integer can be converted to a char, which can be assigned to a string (although the string cannot be initialized to char!). GenericType defines a conversion to int, which makes this member a valid candidate. However, I still argue that this is not a valid conversion, the reason is that using this conversion will result in two custom implicit conversions for assignment, first from GenericType to int, and then from int to string. As stated in the same book 11.4.1, "only one level of user implicit conversion is legal."
endoalir
source share