函数模板可以被重载、显式特化重载、普通函数重载。如以下函数模板的重载声明:
namespace LDQ_TEST
{
//函数模板定义
template< typename T >
T sum( T, int );
//T == double的显式特化
template<> double sum< double >( double, int );
//普通(非模板)函数
double sum( double, double );
}
对于一个该函数的调用,编译器是怎样选择调用的函数实例的呢。我们可以对该函数模板做以下定义和调用测试出来:
template< typename T >
T
LDQ_TEST::sum( T t, int ival )
{
std::cout <<"调用函数模板" <<std::endl;
return t;
}
template<>
double
LDQ_TEST::sum<double>( double dval, int ival )
{
std::cout <<"调用模板特化函数" <<std::endl;
return dval;
}
double
LDQ_TEST::sum( double dval1, double dval2 )
{
std::cout <<"调用普通函数" <<std::endl;
return dval1;
}
double dval = 3;
int ival = 2;
LDQ_TEST::sum( dval, ival ); //调用模板特化函数
LDQ_TEST::sum( dval, dval ); //调用普通函数
LDQ_TEST::sum( ival, ival ); //调用函数模板
1.如果参数类型以及返回类型完全匹配,则选择普通函数或者模板显式特化函数作为调用的函数实例。
2.否则,如果模板函数能够推导出一个参数类型以及返回类型完全匹配的函数实例,则选择函数模板。
3.否则,如果调用函数的实参以及返回类型能够进行隐式转换成与普通函数或者模板显式特化函数的类型匹配,则选择普通函数或者模板显式特化函数。
4.如果以上三条都不能匹配,则函数匹配失败,发生编译错误。