Unexpected function deduction is happening in the following program. -
Case I -
template <typename T, typename>
void foo(T x, int) {
cout << "In int foo\n";
}
template <typename T>
void foo(T x, char) {
cout << "In char foo\n";
}
int main() {
string s = "Hello World";
foo(s, (int) 1);
}
Output
In char foo
Case II -
template <typename T>
void foo(T x, int) {
cout << "In int foo\n";
}
template <typename T>
void foo(T x, char) {
cout << "In char foo\n";
}
int main() {
string s = "Hello World";
foo(s, (int) 1);
}
Output
In int foo
For case II, I just removed the last template parameter typename from the first function. Could someone please explain what's happening here?
In this function,
template <typename T, typename>
void foo(T x, int) {
cout << "In int foo\n";
}
You tell the compiler that,
T
and the other is int
.When compiling foo(s, (int) 1);
, the compiler knows the type of T
as its given by the argument, the second argument is also given. But the second template argument is unknown. So the compiler tries to find the other most suitable one, which in this case the other foo
function.
This time the compiler tests it out once again and it passes, as int
can be implicitly converted to char
. This is why it outputs In char foo
in the first case.
In the second case, since there are no unknown types, the most suitable one is the first function void foo(T x, int)
. That's because the second argument type is int
and the function's second parameter types is also int
.
To resolve the issue in the first case, you can provide a default type argument to the template. This way it knows the second type parameter, thus will work without an issue.
template <typename T, typename = void>
void foo(T x, int) {
cout << "In int foo\n";
}