views:

52

answers:

2

I'm reading Stroustrup's book, the section on overloading and related ambiguities.

There's an example as follows:

void f1(char);
void f1(long);

void k(int i)
{
    f1(i);    //ambiguous: f1(char) or f1(long)
}

As the comment states, the call is ambiguous. Why?

The previous section in the book stated 5 rules based on matching formal and actual parameters. So shouldn't the above function call come under rule 2, regarding "promotions"? My guess was that 'i' should be promoted to a long, and that's that.

As per the comment, it seems that a int to char conversion (a demotion?) also comes under rule 2?

A: 

An int can be converted to a char, and a int can also be converted to a long.

So in that sense it is ambiguous, as the compiler cannot tell which you're calling.

Tony
+6  A: 

Anything goint from int above isn't a promotion anymore. Anything going less than int to int is a promotion (except for rare cases - see below)

So if you change to the following it becomes non-ambiguous, choosing the first one

void f1(int);
void f1(long);

void k(unsigned short i) {
    f1(i);
}

Notice that this is only true on platforms where int can store all values of unsigned short. On platforms where that is not the case, this won't be a promotion and the call is ambiguous. On such platforms, the type unsigned int will be the promotion target.

Sort of the same thing happens with floating points. Converting float to double is a promotion, but double to long double isn't a promotion. In this case, C++ differs from C, where double to long double is a promotion likewise (however, it doesn't have overloading anyway).

Johannes Schaub - litb
"Notice that this is only true on platforms where int can store all values of short. On platforms where that is not the case [...]" I don't think that such platforms may exist, the C standard (§6.2.5.8) specifies that "For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type.", and at §6.3.1.1.1 it says "The rank of [...] int [...] shall be greater than the rank of short int.". Just nitpicking of course, I upvoted your answer. :)
Matteo Italia
@Matteo ah right, good point - i will want to use `unsigned short`. Thanks for upvote. I was clearly wrong on the internet :)
Johannes Schaub - litb
Got it :D (http://xkcd.com/386/)
Matteo Italia
+1 for a really thorough answer regarding implicit conversions and parameter matching.