Template function overload resolution
Consider this code:
#include <iostream>
void func(int&)
{
std::cout << "mutable" << std::endl;
}
void func(const int&)
{
std::cout << "const" << std::endl;
}
template<typename T>
void tpl_func(T&)
{
std::cout << "mutable_tpl" << std::endl;
}
template<typename T>
void tpl_func(const T&)
{
std::cout << "const_tpl" << std::endl;
}
class number
{
public:
operator int&()
{
return nb_;
}
operator const int&()
{
return nb_;
}
private:
int nb_ = 42;
};
int main()
{
number n;
func(n); // This produces: error: call to 'func' is ambiguous
tpl_func(n); // This compiles fine
}
Tested with clang3.5
Questions:
- Why is the overload resolution for template functions not ambiguous?
- What rules determine which overload is selected?
Because in func(n)
there is an implicit function call (operator int-conversion), which is ambiguous (you can choose either of the two), and in tpl_func(n)
you are NOT int-convertting, that is, the template outputs tpl_func<number>(number &)
, since it n
is an lvalue.
func(n);
requires conversion, both func
are viable, and overload is ambiguous.
tpl_func(n);
has an exact match ( template<typename T> void tpl_func(T&)
).