I was studying about overloading and I am completely getting confused with promotions. I looked at few articles in SO (implicit conversion sequence in function overloading) and I am sure some more are available, but could not find the right article. I was also referring to http://www.dcs.bbk.ac.uk/~roger/cpp/week20.htm. I was looking at C++ Programming special edition by Stroustrup and came across following explanation.
Finding the right version to call from a set of overloaded functions is done by looking for a best match between the type of the argument expression and the parameters (formal arguments) of the functions. To approximate our notions of what is reasonable, a series of criteria are tried in order: 1 Exact match [2] Match using promotions; [3] Match using standard conversions [4] Match using user-defined conversions [5] Match using the ellipsis ......
void print(int);
void print(double);
void print(long);
void print(char);
void h(char c, int i, short s, float f)
{
print(s); // integral promotion: invoke print(int)
print(f); // float to double promotion: print(double)
}
I wrote below code. I was thinking that if I call the function with value of 1, func1(long) will be called because promotion takes place. But I get error message "error: call of overloaded 'func1(int)' is ambiguous". It is not calling the function with even unsigned char type of variable.
Also if I pass call func1(3.4f), func1(double) is called and promotion takes place as per my expectation. Why 1 is not promoted to long int but why float is promoted to double? What integer promotions takeplace?
void func1(unsigned char speed)
{
cout<<"Func1 with unsigned char: speed =" << speed <<" RPM\n";
}
void func1(long speed)
{
cout<<"Func1 with long Int: speed =" << speed <<" RPM\n";
}
void func1(double speed)
{
cout<<"Func1 with double: speed =" << speed <<" RPM\n";
}
int main(void)
{
func1(1);
func1(3.4f);
return(0);
}
The standard specifies:
[C++11: 4.13/1]:
("Integer conversion rank")Every integer type has an integer conversion rank defined as follows:
- [..]
- The rank of
long long int
shall be greater than the rank oflong int
, which shall be greater than the rank ofint
, which shall be greater than the rank ofshort int
, which shall be greater than the rank of signed char.- The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
- [..]
which calls for ambiguity in your example.
As for func1(3.4f);
, it's just a promotion from float to double, and that's the best match, since the other two overloaded methods have long
and unsigned char
.
Also check this table:
where a subclause specifies:
[conv.fpprom]:
(7.7 Floating-point promotion )
- A prvalue of type
float
can be converted to a prvalue of typedouble
. The value is unchanged.- This conversion is called floating-point promotion.