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 を呼び出し、関数 #2 を呼び出すが、期待どおり #4 を呼び出さない理由を誰か説明してもらえますかfuncT( &x1 );?
私はすでにこの記事http://www.gotw.ca/publications/mill17.htmを読みました。これには、「オーバーロードの解決は特殊化を無視し、基本関数テンプレートのみで動作する」と書かれています。しかし、このロジックによればfuncT( x1 );、#3 ではなく関数 #1 を呼び出す必要があります。私は混乱しています。

4

1 に答える 1

11

関数 #3 と #4 は #1 の特殊化であり、それぞれ #1 と #2 の特殊化ではありません。

これは、コンパイラが最初に #1 と #2 のどちらかを選択することを意味します。funcT(x1) に最適な #1 を選択すると、特殊化 #3 を選択します。funcT(&x1) の場合、#2 が最適なものとして選択され、特殊化は見つかりません。

#4を次のように書くことにより

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

#2 の特殊化になり、funcT(&x1) に対して #4 が呼び出されるという期待される結果が得られます。

別のオプションは、単に書くことです

void funcT(int *arg)

一致する場合、テンプレート化されたバージョンの代わりに通常の関数が常に選択されるためです。

于 2010-02-03T22:10:54.637 に答える