問題は、クラス テンプレートの特殊化の選択がどのように機能するかを理解していないことです。
あなたの専門分野:
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
に、テンプレート引数がtemplate<class T, int I> struct test
特殊化に一致するときに使用される特殊化を作成しますtest<int,J>
。
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
の独立したデフォルト値を同時に設定しながらint
、 のデフォルト タイプとして設定しようとしているようです。あなたの意図は、型と値を指定する、型のみを指定してデフォルト値として 44 を取得する、または値のみを指定して int をデフォルト型として取得できるようにすることだと思います。T
I
残念ながら、そのような独立したデフォルトを指定する方法を知りません。デフォルト ( 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>
、明示的な特殊化があるか、コンパイラが暗黙的な特殊化を生成するかを解決するために、たまたま特殊化を使用することになります。