12

このコードの出力はなぜですか:

#include <iostream>  
template<typename T> void f(T param) 
{ 
   std::cout << "General" << std::endl ; 
} 
template<> void f(int& param) 
{ 
   std::cout << "int&" << std::endl ; 
}  

int main() 
{   
  float x ;  f (x) ;   
  int y ; f (y) ;   
  int& z = y ; f (z) ; 
}  

一般
一般
一般

3つ目は、関数が正確に特殊化されているため、驚くべきことです。int&

編集:私はオーバーロードが適切な解決策かもしれないことを知っています。その背後にあるロジックを学びたいだけです。

4

3 に答える 3

9

yと式の両方のタイプzはですint。式に表示される参照は、参照型を保持しません。代わりに、式の型は参照型になり、式は左辺値になります。

したがって、どちらの場合も、Tはに推論されint、したがって、明示的な特殊化はまったく使用されません。

注意すべき重要なことは(別の人が言ったように、実際にオーバーロードを使用する必要があることを除いて)、テンプレートに非参照関数パラメーターがあることです。引数の型に対する推論がT行われる前に、引数の型は配列から最初の要素へのポインターに変換されます(関数の場合、引数は関数ポインターに変換されます)。したがって、非参照関数パラメーターを持つ関数テンプレートでは、とにかく正確な推論ができません。

于 2011-01-13T08:17:11.267 に答える
1

参照は単なるエイリアスであり、タイプではありません。したがって、f(z)を呼び出すと、最初のバージョンがT = intと一致します。これは、T = int&よりも優れたオプションです。TをT&に変更すると、int引数とint&引数の両方が2番目のバージョンを呼び出します。

于 2011-01-13T07:18:17.117 に答える
0

私はそれが答えではないことを知っていますが、私見では、構造体のアプローチのような特性でこれを試すことができます:

template<typename T>
struct value_traits
{
    static void print(){std::cout << "General" << std::endl ;} 
};

template<>
struct value_traits<const long>
{
    static void print(){std::cout << "const long" << std::endl ;} 
};

template<>
struct value_traits<std::vector<unsigned char> >
{
    static void print(){std::cout << "std::vector<unsigned char>" << std::endl ; }
};

template<>
struct value_traits<const int>
{
       static void print(){std::cout << "const int" << std::endl ;} 
};
于 2011-01-13T10:23:46.647 に答える