I'm reading the standard and trying to figure out why this code won't be resolved without a cast.
void foo(char c) { } // Way bigger than char void foo(unsigned long int) { } int main() { foo(123456789); // ambiguous foo((unsigned long int) 123456789); // works }
Here's what it says:
4.13 Integer conversion rank [conv.rank]
Every integer type has an integer conversion rank defined as follows:
— The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
— The rank of char shall equal the rank of signed char and unsigned char.
In particular, what rustles my jimmies is that it doesn't say ANY unsigned integral type, just unsigned char. My guess is that char is being promoted to an unsigned type via conversion. Is this true?
It has little to do with rank of the type defined in 4.13. 4.13 defined internal rankings used to describe integral promotions and usual arithmetic conversions. They by itself do not directly affect overload resolution. Rankings relevant to overload resolution are defined in "13.3.3.1.1 Standard conversion sequences" and then used in "13.3.3.2 Ranking implicit conversion sequences".
So, it is about rank of the conversion as defined under 13.3. 123456789
is an integer literal of type int
on your platform. This means that calling both char
and unsigned long
versions of your function requires an implicit conversion from int
to char
or from int
to unsigned long
. In both cases we have conversions of "integral conversion" type. That means that both functions are equally "bad" in this case. Hence the ambiguity.
If one of these functions required a mere integral promotion (as opposed to integral conversion), it would win the resolution and the call would be considered unambiguous. But alas both of your functions require integral conversions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With