What is operator overloading?
Sbi's famous Operator overloading faq answers this in great detail.
Why are the two function
versions in OP allowed to exist?
Notice they take different function parameter types(int
and float
) and hence qualify as valid function overloads.
What is overload resolution?
It is the process of selecting the most appropriate function/operator by the compiler implementation. If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails and the invocation is treated as ill-formed and compiler provides a diagnostic. The compiler uses implicit conversion sequence to find the best match function.
C++03 Standard 13.3.3.1 Implicit Conversions:
An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called.
The implicit conversion sequences can be one of the following categories:
- A standard conversion sequence(13.3.3.1.1)
- A user-defined conversion sequence(13.3.3.1.2)
- An ellipsis conversion sequence(13.3.3.1.3)
Note that each of these are ranked to determine the best viable function. The best viable function is the one all whose parameters have either better or equal-ranked implicit conversion sequences than all of the other viable functions.The standard details each of these in detail in respective sections. The standard conversion sequence is relevant to this case, it is summarized as:
With enough background on overloading resolution.
let us examine the code examples in OP:
function(1.2,2.2);
Important Rule: 1.2
and 2.2
are literals and they are treated as a double
data type.
During implicit conversion sequences mapping:
Both the function parameter literals with double
type need a conversion rank to either call the float
or int
version and none is a better match than other, they score exactly the same on conversion rank. The compiler is unable to detect the best viable match and it reports an ambiguity.
function(1.2,2);
During implicit conversion sequence mapping:
One of the function parameters 2
has an exact match with the int
function version while another 1.2
has a conversion rank. For function which takes float
as parameters the implicit conversion sequences for both parameters are of conversion rank.
So the function which takes int
version scores better than the float
version and is the best match and gets called.
How to resolve overloading ambiguity errors?
If you don't want the implicit conversion sequence mapping to throw you off, just provide functions and call them in such a way so that the parameters are a exact match. Since exact match scores over all others, You have a definite guarantee of your desired function getting called. In your case there are two ways to do this:
Solution 1:
Call the function so that parameters are exact match to the functions available.
function(1.2f,2.2f);
Since 1.2f
and 2.2f
are treated as float
types they match exactly to the float
function version.
Solution 2:
Provide a function overload which exactly matches the parameter type in called function.
function(double, double){}
Since 1.2
and 2.2
are treated as double
the called function is exact match to this overload.