George Skelton George Skelton - 1 month ago 6
C++ Question

C++ ambiguous call to overloaded function with unsigned int

This seems inconsistent. I have 3 functions

f
overloaded for signed types
short
,
int
and
long long
. If you pass an
unsigned short
then it gets promoted to the next biggest signed type
int
. However if you pass
unsigned int
then it doesn't get promoted to signed
long long
which is what I would expect, rather compiler complains about ambiguous call to overloaded function.

void f(short x) { std::printf("f(short)\n"); }
void f(int x) { std::printf("f(int)\n"); }
void f(long long x) { std::printf("f(long long)\n"); }

int main()
{
f((unsigned short)0); // Fine: calls f(int)
// f((unsigned int)0); // Ambiguous: could be f(short), f(int) or f(long long)
}

Answer

It is inconsistent, yes, but it is The Way The Language Is, and you have to cope, e.g. if you want f((unsigned int)0) to call the long long overload, then provide a wrapper,

inline void f(unsigned int x) { f((long long)x); }

The designers of C++ would have ideally liked to make both of your cases fail overload resolution. But there was this legacy thing (dating all the way back to "K&R" C), called "default argument promotion", that, essentially, says the compiler will implicitly convert all integer types narrower than int to int if necessary to match a function signature, and all floating point types narrower than double to double ditto.

So it's the f((unsigned short)0) case that is the odd man out, really.

Comments