2012-01-11 12 views
3

例:明示的と部分的な専門化の構文の違いはなぜですか?

template <typename T, typename U> 
struct A { 
    void Print() {} 
}; 

template <> 
void A<int, float>::Print() {} // Okay     

template <typename T> 
void A<T, char>::Print() {} // Will produce error 

質問:

私はあなたがそれを動作させるために上記のコードでクラステンプレート部分的な特殊化を定義する必要があり、私もThe members of the class template partial specialization are unrelated to the members of the primary template (§ 14.5.5.3)その標準から知っていることを知っています。しかし、なぜExplosationの専門化と部分的な専門化の間の構文の違いはありますか?

答えて

0

機能テンプレートを部分的に、完全にしか特殊化できません。

最初のインスタンスは、クラステンプレートのメンバー関数自体が関数テンプレートであるため、制限が適用されるという事実を利用しています。

クラステンプレートを部分的に特殊化すると、まったく新しいクラステンプレートが作成されます。これは、新たに定義する必要があります。

+1

"クラステンプレートの関数自体が関数テンプレート" - クラスの外部で定義されたクラステンプレートのメンバ関数は、*関数テンプレートのように定義されます。しかし、彼らは本当に同等ですか? –

+0

@Jesse no彼らは同等ではありません。クラステンプレートのメンバ関数の "templatiness"を記述する用語はありません。それらは関数テンプレートではありません。一部の人々はそれらを「テンプレート」と呼びます。対応する問題はhttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1253です。 –

+0

@ JohannesSchaub-litb:説明をいただきありがとうございます。うまくいけば、活発な問題の説明がすぐに追加されることを願っています。 –

0
template <typename T> 
void A<T, char>::Print() {} // Will produce error 

あなたは、次のとおりです。

  1. 再定義する機能void Print() {}宣言したときに(それが既に定義されている、あなたは{}がある参照
  2. 一致しないテンプレート引数リストを持ちます宣言:template <typename T, typename U> void Print()

実際、宣言時に関数を定義していなくても、宣言と定義が一致しないため、コンパイラは元のテンプレートの定義や特殊なテンプレートの宣言を見つけることができません。

だけでなく、特殊な構造体を持っている必要があり、構造体に関連している機能に特化したテンプレート関数は、このコードは動作します:テンプレート関数は、それがテンプレート構造体だ中で宣言されてい

template <typename T, typename U> 
struct A { 
    void Print() {} 
}; 

template <> 
void A<int, float>::Print() {} // Okay     


template <typename T> 
struct A<T,char> 
{ 
    void Print(); 
}; 

template <typename T> 
void A<T,char>::Print() {} 

ので。

+0

この説明についてはわかりません。標準からの引用です: 'プライマリテンプレートのメンバーの定義は、クラステンプレートの部分スペシャリゼーションのメンバーのための定義として使用されることはありません。 ' –

+0

私は引用と説明の間に対立は見ません、何がポイントですかあなたが持っている? –

+1

're-defining'と述べましたが、クラステンプレートの特殊化は、プライマリテンプレートとは無関係の別のテンプレートであるため、再定義は必要ありません。コンパイラは 'A 'を見ると特殊な定義が必要です。それをコンパイルしてエラーを見てみましたか?関数を宣言するときに関数を定義しなくても、同じエラーが発生します(ただし、エラーが常に私に伝えるものを信頼してはいけません)。 –