2011-07-18 12 views
2

次のコードを見ると、私は3行目に混乱しています。
3行目は基本テンプレートの特別なケースではなく、「クラス過負荷」のようです。しかし、それは正常にコンパイルすることができます。
行7のobj1は、行3にしたがって定義されていますが、コンパイルに失敗しました。
どうしてですか?
C++クラステンプレートの専門化の質問

template<typename S,int T, void(* U)()> class Bar{}; // Base template 
template<int T, void(* U)()> class Bar<double, T, U>{}; // Specialization, which is good 
template<int T, void(* U)()> class Bar<double, U, T>{}; // Also good, how come? 

void func(){}; 
int main(){ 
    //Bar<double, func, 1> obj1; // Error, from line 3 
} 

答えて

3

限りそのフォームはどこにも使用されていないよう - コンパイラは文句を言うことはありません。それが使用され、コンパイラがインスタンス化する必要がある場合、それは不平を言うでしょう。つまり、コメントを外すとエラーになります。この時点で、コンパイラは欠陥のある部分的な特殊化を認識します。

+0

コンパイラはいつ呼び出すべきですか? 4行目に別の行を追加すると、template class Bar {};これは使用されず、コンパイラーはインスタンス化されませんが、コンパイルに失敗しました。 –

+0

@John、私が言ったように、あなたがその型のインスタンスを宣言しようとすると(obj1の行のコメントを外すように)(その時点でインスタンス化しようとすると)それは文句を言うでしょう。あなたがしなければ、それはテンプレートの美しさです... – Nim

+0

@John、それは別の問題です。そこには 'Bar'よりも多くのテンプレートパラメータがあります。 – Nim

4

テンプレートは特別です。あなたが使用しないものは、実際にインスタンス化(コンパイル)されません。これにより、いくつかの一般的なテンプレートで多くのクールなことを行うことができます。たとえば、特定の型パラメータでコンパイルしないメンバ関数を定義できますが、メンバ関数を使用しない限り、エラーは発生しません。

これはまたあなたを噛むことがあります:Line 3は実際には整形式ではありません - それはBarの非コンパイル化特殊化ですが、実際にmain()関数で使用するまで気付かないでしょう。

+0

答えをありがとう。以下のNimに続く私のコメントを見てください。 –