I have two template max
functions and try to call one of them.
#include <iostream>
#include <type_traits>
template <typename T1, typename T2>
auto max(T1 a, T2 b) {
return b < a ? a : b;
}
template <typename RT, typename T1, typename T2>
RT max(T1 a, T2 b) {
return b < a ? a : b;
}
int main(void) {
max<int>(4, 7.2);
return 0;
}
Here, max<int>(4, 7.2)
causes ambiguity, generating the compilation error.
<source>: In function 'int main()':
<source>:15:13: error: call of overloaded 'max<int>(int, double)' is ambiguous
15 | max<int>(4, 7.2);
| ~~~~~~~~^~~~~~~~
<source>:5:6: note: candidate: 'auto max(T1, T2) [with T1 = int; T2 = double]'
5 | auto max(T1 a, T2 b) {
| ^~~
<source>:10:4: note: candidate: 'RT max(T1, T2) [with RT = int; T1 = int; T2 = double]'
10 | RT max(T1 a, T2 b) {
| ^~~
Compiler returned: 1
Two max
functions can be interpreted as follows when calling max<int>(4, 7.2)
:
double max(int a, double b) {
return b < static_cast<double>(a) ? static_cast<double>(a) : b;
}
int max(int a, double b) {
return b < static_cast<double>(a) ? static_cast<double>(a) : b;
}
A compiler might prefer the first one because it has a higher precision when returning value.
Why does ambiguity happen in this case?
The return type is not consider in function overloading since it can result in ambiguity of which function to call. For example:
int foo();
double foo();
int x = foo(); // Which one should be called?