2012-07-23 6 views
5

に私は次のコードを持っている:はC++ 11

template<class T, int I=44> struct test {T j = I;}; 

template<int J> struct test<int, J> {int j = J;}; 

int main() 
{ 
    test<55> jj; 

    std::cout << jj.j << std::endl; 
    return(1); 
} 

コンパイラ(打ち鳴らすを)私は理由を理解していないtest<55> jj

ラインだけ文句を言いますか?回避策はありますか?

そして、その行について不平を言うと、なぜ2番目のテンプレート定義について文句を言わないのですか?

ありがとうございます。

メッセージがある:

enable.cpp:17:8: error: template argument for template type parameter must be a type 
test<55> jj; 
    ^~ 
enable.cpp:9:16: note: template parameter is declared here 
template<class T, int I=44> struct test 
+0

エラーメッセージをリンクできますか? – Morwenn

答えて

6

問題は、クラステンプレートの特殊化を選択する仕組みが理解できていないことです。

あなたの分業:

template<int J> struct test<int, J> {int j = J;}; 

は、あなただけの単一のintテンプレートパラメータを渡すために持っているため、テンプレートを作成しません。

test<55> jj; // doesn't work because there's no template<int J> struct test 

は、代わりにそれが何template<class T, int I> struct testにテンプレート引数が専門、すなわちtest<int,J>と一致するときに使用されるtemplate<class T, int I> struct testの特殊化を作成することです。

test<int,55> jj; // uses the specialization template<int J> struct test<int, J> 

ここでは、標準からキーの引用です:

型の名前のクラステンプレートの特殊化を意味し、(例えば、 A<int, int, 1>)引数リストは、テンプレートパラメータにの リストと一致するものプライマリテンプレート。 特殊化のテンプレート引数は、プライマリテンプレートの引数から導き出されます。[重点を加え]

                                                                                                                                                                      - 14.5.5.1 [temp.class.spec.match] P4


あなたが設定しようとしているように見えます Tのデフォルトタイプとして intと同時に、独立した Iのデフォルト値です。あなたの目的は、型と値を指定し、型だけを指定してデフォルト値として44を取得したり、値を指定してint型をデフォルト型として取得することです。

残念ながら、このような独立したデフォルトを指定する方法はわかりません。デフォルト(template<class T=int, int I=44> struct test)を指定することもできますが、デフォルトのタイプを取得する場合はデフォルト値を受け入れる必要があります。

しかしあなたは、あなたが行うことができます2番目の名前を使用するために喜んでいる場合:

template <int I> 
using test_int = test<int, I>; 

これは、あなたが唯一の値を指定する必要があることなど、テンプレートのエイリアスを作成します。

test_int<55> jj; 

そして、特定の特殊化があるかどうか、またはコンパイラが暗黙的なものを生成するかどうかを特定するために、test<int, I>が何らかの特殊化を使用して終了します。

3

55は、型自体ではないので、コンパイラは、これが機能しない55とテンプレートパラメータ(class T)をインスタンス化しようとするため、最初のエラーが発生し、しかしそれのインスタンス化。ただし、test<int>は、テンプレートの署名によって要求されるように、テンプレートのparaterがタイプであるために機能します。

代わりに、タイプの「カリング」が必要です。テンプレートエイリアシング:

ここ
template <typename T> 
struct test2 = using test<T, 55>; 

あなただけの固定された第2のパラメータとして55を選択するTを提供する必要があります。しかし、具体的にはのように具体的にTと指定することで、そのタイプを使用する必要があります。ここで

template <int I> 
using test3 = test<int, I>; 

あなたはintに最初の型パラメータを修正し、あなたのコードで行ったようにあなたがそれを使用することができます::

コメントはあなたにも、以下のバリアントに興味がある可能性が示されました

test3<55> t; 
+0

コードには非常に多くのことが間違っています...まず、構文が明らかに失敗します。第二に、彼はタイプを特定したくない。第三に、それは部分的な専門性ではない。 – Xeo

+3

特殊化はTをintに修正し、使用する値としてのみ55を使用します。おそらく 'template test_int = test ;'を探しています。 – bames53

+0

答えのテンプレートエイリアシングは、ユーザーが実際に望んでいないデフォルト値と同じです。 –