5

次のコードがあります。

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);
}

コンパイラ(clang)は行についてのみ不平を言います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
4

2 に答える 2

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に、テンプレート引数が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 をデフォルト型として取得できるようにすることだと思います。TI

残念ながら、そのような独立したデフォルトを指定する方法を知りません。デフォルト ( 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>、明示的な特殊化があるか、コンパイラが暗黙的な特殊化を生成するかを解決するために、たまたま特殊化を使用することになります。

于 2012-07-23T16:09:50.530 に答える
3

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

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

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

T ここでは、固定の 2 番目のパラメーターとして 55 を選択するための a のみを指定する必要があります。Tただし、具体的な を指定して、そのタイプを使用する必要がありますtest2<double>

コメントは、次のバリアントにも興味がある可能性があることを示しています。

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

ここでは、最初の型パラメーターを int に修正します。これにより、コードで行ったように使用できます。

test3<55> t;
于 2012-07-23T15:36:16.317 に答える