转载自:http://blog.csdn.net/kannju/article/details/6740862,kannju的专栏,感谢分享!
函数模板可以被重载、显式特化重载、普通函数重载。如以下函数模板的重载声明:
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 ); //调用函数模板
template< typename T >
T
LDQ_TEST::sum( T t )
{
std::cout <<"调用函数模板" <<std::endl;
return t;
}
template<>
double
LDQ_TEST::sum<double>( double dval )
{
std::cout <<"调用模板特化函数" <<std::endl;
return dval;
}
double
LDQ_TEST::sum( double dval1 )
{
std::cout <<"调用普通函数" <<std::endl;
return dval1;
}
double dval = 3;
LDQ_TEST::sum( dval ); //调用模板特化函数
从调用函数的输出,我们就可以为同名的函数模板、模板显式特化函数和普通函数的优先选择顺序,总结出以下4点:
1.如果参数类型以及返回类型完全匹配,则选择普通函数或者模板显式特化函数作为调用的函数实例。(普通函数或者模板显式特化函数都满足的条件则先调用模板显性特化函数)
2.否则,如果模板函数能够推导出一个参数类型以及返回类型完全匹配的函数实例,则选择函数模板。
3.否则,如果调用函数的实参以及返回类型能够进行隐式转换成与普通函数或者模板显式特化函数的类型匹配,则选择普通函数或者模板显式特化函数。
4.如果以上三条都不能匹配,则函数匹配失败,发生编译错误。