Search code examples
c++compiler-errorsoverloadingoverload-resolution

Function overloading getting ambiguous


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?


Solution

  • 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. enter image description here

    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.