9

我有以下一组模板:

//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。我很困惑。

4

1 回答 1

11

函数#3 和#4 是#1 的特化,而不是#1 和#2 的特化。

这意味着您的编译器将首先在#1 和#2 之间进行选择。当它选择 #1 最适合 funcT(x1) 时,它会选择特化 #3。对于 funcT(&x1),它选择 #2 作为最佳拟合并且没有找到特化。

通过将#4 写为

template<> void funcT<>( int * arg )

它成为#2 的特化,你会得到#4 被调用为funcT(&x1) 的预期结果。

另一种选择是简单地写

void funcT(int *arg)

因为如果它们匹配,将始终选择常规函数而不是模板版本。

于 2010-02-03T22:10:54.637 回答