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?
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.
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.
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).