我有以下模板集:
//1
template< typename T > void funcT( T arg )
{
std::cout<<"1: template< typename T > void funcT( T arg )";
}
//2
template< typename T > void funcT( T * arg )
{
std::cout<<"2: template< typename T > void funcT( T * arg )";
}
//3
template<> void funcT< int >( int arg )
{
std::cout<<"3: template<> void funcT< int >( int arg )";
}
//4
template<> void funcT< int * >( int * arg )
{
std::cout<<"4: template<> void funcT< int *>( int * arg )";
}
//...
int x1 = 10;
funcT( x1 );
funcT( &x1 );
有人可以解释为什么funcT( x1 );
调用函数#3而funcT( &x1 );
调用函数#2但不按预期调用#4?
我已经阅读了这篇文章http://www.gotw.ca/publications/mill17.htm,其中说“重载决策忽略了特殊化并仅对基本功能模板进行操作”。但根据这个逻辑,funcT( x1 );
应该调用#1函数,而不是#3。我很困惑。
答案 0 :(得分:11)
函数#3和#4是#1的特化,而不是#1和#2的特化。
这意味着您的编译器将首先在#1和#2之间进行选择。当它选择#1最适合funcT(x1)时,它会选择专门化#3。对于funcT(&amp; x1),它选择#2作为最佳拟合并且没有找到特化。
将#4写为
template<> void funcT<>( int * arg )
它成为#2的特化,你将得到预期的结果,即为funcT(&amp; x1)调用#4。
另一种选择是简单地写
void funcT(int *arg)
因为如果它们匹配,将始终选择常规函数而不是模板化版本。