1

Foo2つ(またはそれ以上)のテンプレート引数を取るテンプレートクラスがあります。その型を別のクラスで使用したいBar。エラーなしでコンパイルされる次の簡単な例を参照してください。

template <typename T, typename U> class Foo { };
template <typename T, typename U> class Bar { };
int main()
{
  Bar<int, char> bar; // quick example -- int & char could be any 2 types
  return 0;
}

上記は、特にFoo多くのテンプレート引数を取り、プログラマーがそれらすべてを再入力する必要がある場合は、やや面倒です。代わりに次のようなものが欲しいのですが、コンパイルされません:

template <typename T, typename U> class Foo { };
template <typename T, typename U> class Bar; // base
template <typename T, typename U> class Bar< Foo<T, U> > { }; // specialization
int main()
{
  typedef Foo<int, char> FooType;
  Bar<FooType> bar;
  return 0;
}
test.cpp:3:60:エラー:テンプレート引数の数が間違っています(1、2である必要があります)
test.cpp:2:45:エラー:「テンプレートクラスバー」に提供
test.cpp:関数内'int main()':
test.cpp:7:18:エラー:テンプレート引数の数が間違っています(1、2である必要があります)
test.cpp:2:45:エラー:「テンプレートクラスバー」に提供
test.cpp:7:23:エラー:';'の前の宣言に無効なタイプがあります トークン

この部分的な特殊化のイディオムは単一のテンプレート引数に対して正常に機能するため、私は特に困惑しています。「テンプレートのクラス全体の専門化」というタイトルの質問を参照してください。

編集少なくとも私の目的では、次のようにC++11可変個引数テンプレートを使用してこれを回避できることに気付きました。ただし、2番目の例が機能しない理由を知りたいのですが。

template <typename... FooTypes> class Bar;
template <typename... FooTypes> class Bar< Foo<FooTypes...> > { };
4

2 に答える 2

3

クラステンプレートBar<T, U>は2つのテンプレート引数を取りますが、スペシャライゼーションには1つしか与えられていません。

template <typename T, typename U> class Bar<Foo<T, U> > {};

Barテンプレートの引数を1つだけ取り、それに応じてそれを専門化するという意味ですか?

template <typename T> class Bar;
template <typename T, typename U> class Bar<Foo<T, U> > {};

特殊化は異なる数のテンプレートパラメータに依存する可能性がありますが、特殊化は同じ数の引数を取得する必要があることに注意してください。また、逆の方法でも機能します。完全なスペシャライゼーションにテンプレートパラメータを含めることはできません。

template <> class Bar<int> {};
于 2012-10-08T18:11:45.817 に答える
2

私はあなたがこの行で何をしようとしているのかについて少し混乱しています:

template <typename T, typename U> class Bar< Foo<T, U> > { }; // specialization

テンプレートには、タイプパラメータとしてTとUの2つのタイプが必要であると述べています。ただし、Foo自体は1つのタイプにすぎません。このタイプは、これら2つの引数を使用してFooテンプレートをインスタンス化することによって作成されます。

両方の場所でTとUを使用したので、TとUを取得して決定することを期待しているようですが、2つのタイプのテンプレートの特殊化に対して1つのタイプの引数しか提供しなかったという事実を回避するものではありません。

于 2012-10-08T18:06:37.910 に答える