浅谈模板函数的重载解析优先顺序

转载自: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.如果以上三条都不能匹配,则函数匹配失败,发生编译错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值