Function overloading getting ambiguous

2019-08-10 07:33发布

问题:

When overloading functions:

void add(int a)
{
    a=7;
    cout<<"int";
}
void add(double a)
{
    a=8.4;
    cout<<"double";
}
void add(int *b)
{
    *b=4;
    cout<<"pointer";
}
int main()
{
    char i='a';   //char
    add(i);
    return 0;
}

OUTPUT: int

This worked fine inspite of no function with data type char as parameter.

But when compiled below code:

void add(char a)
{
    a='a';
    cout<<"int";
}
void add(double a)
{
    a=8.4;
    cout<<"double";
}
void add(int *b)
{
    *b=4;
    cout<<"pointer";
}
int main()
{
    int i=4;  //int
    add(i);
    return 0;
}

Gave error(compiler gcc):

cpp|21|error: call of overloaded 'add(int&)' is ambiguous

What is the logic behind this? And how to track the control passing or output of such codes?

回答1:

This example boils down to the difference between Integer Promotion and Integer Conversion. A promotion is, in short:

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. [...] These conversions are called integral promotions.

whereas an integer conversion is more general:

A prvalue of an integer type can be converted to a prvalue of another integer type. [...] The conversions allowed as integral promotions are excluded from the set of integral conversions.

An integral promotion is a better conversion than an integral conversion for the purposes of overload resolution.


In the first example, we have:

add(int );    // (1)
add(double ); // (2)
add(int* );   // (3)

and are calling with a char. Only the first two are viable, both involve a conversion. (1) involves an Integer Promotion, which has rank Promotion. (2) involves a Floating-Integral Conversion, which has rank Conversion. Promotion is a higher rank than Conversion, so (1) is unambiguously preferred.

Now, in the second example, we have:

add(char );   // (1)
add(double ); // (2)
add(int* );   // (3)

and are calling with an int. Once again, only the first two are viable, and both involve a conversion. (1) this time involves an Integral Conversion (sincechar has lower rank than int) and (2) still involves a Floating-integral conversion, both of which have the same rank: Conversion. As we have two conversions of the same rank, there is no "best" conversion, so there is no best viable candidate. Thus, we have an ambiguous resolution.



回答2:

Reason is when there is no exact type match, compiler looks for the closest match. Thats why when it was - char i='a'; the closest match was void add(int a)

but when it is int i=4; //int there are 2 match now. so that is why it is ambiguous.



回答3:

A char fits into an int without overflowing or losing precision, which explains the first code.

But an int doesn't fit into a char (overflow), double (lack of precision), or int* (incompatible type).