The compiler was confused when you called volume(double, double, int)
as should compiler convert doubles to ints and call volume(int, int, int)
or should it convert int to double and call volume(double, double, double)
.
For Advanced Readers
How does overloading works?
There are 3 steps to overload resolution.
Finding the Candidate Functions : The functions with same name as called function are called candidate functions. In your case, all functions named volume
are candidate Functions, because you called volume(..)
Finding the Viable Functions :
A function must meet two tests to be viable First, The function must have same number of parameters as there are arguments in the call. (except default arguments). Second, Each argument must match--or be convertible to the types of it's corresponding parameters. In your case, volume(int,int,int) and volume(double, double, double)
are viable functions.
Finding the best match if any :
Last step of overload resolution determines the viable function(s) that has best match for the arguments. The best here means -- a exact type match is better than a match that requires a conversion from argument to parameters type. In your case there is no best match. Your call volume(double, double, int)
doesn't matches with any viable function.
Problem with multiple parameters
Let's look at this example of rather a simpler case
void foo(int x, int y);
void foo(double x, double y);
Suppose we make a call as
foo(4.2, 5) //double and int
The above two foo, are candidate Functions (same name).
And they both are viable function as well because call can be made by conversion and both take 2 arguments.
So now compiler decides argument by argument which function is best match.
There is a match if there is only and only one function for which :
1. The match for each argument is no worse than match required by any other viable function
2. There is at least one argument for which the match is better than the match provided by any other viable function
So, when compiler checks first argument by first parameter of viable function, it chooses that foo(double, double)
is the best match, but when it checks the second argument it finds that foo(int, int)
is a better match.
The call is therefore ambiguous. Each viable function is better match on one of the argument to the call.
Solution
To resolve such ambiguity, you need to make sure that compiler is able to find best matches. So you need to convert the arguments explicitly. In your case you can either convert doubles to ints or last int to double. This call will not be ambiguous :
volume(2.0, 9.7, static_cast<double>(3));
Why static_cast
?? Well in general you can directly write 3.0 instead and it will work fine but you cannot do it with some variables let's say
int x = 10;
float a= 2.1, b=4.8;
for(int t=1;t<=x;t++){
volume(a,b,static_cast<double>(t));
//do something with t here
}
NOTE
You shouldn't try to explicitly convert arguments in function call for overloading in general.
Rather you should make a new overloaded function with what you are trying to do. But I hope you are doing this just for learning, it's all fine. In projects you must avoid these explicit conversions.