11

テンプレート テンプレート パラメーターを使用するのに問題があります。以下は、非常に単純化された例です。

template <typename T> 
struct Foo {
  T t;
};

template <template <class X> class T>
struct Bar {
  T<X> data;
  X x;
};

int main()
{
  Bar<Foo<int>> a;
}

コンパイラ (g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2) は、次のエラーを報告します。

main.cpp:8:5: error: ‘X’ was not declared in this scope
   T<X> data;
     ^

main.cpp:8:6: error: template argument 1 is invalid
   T<X> data;
      ^

何が問題なのですか?

4

4 に答える 4

11

だから私はそうしたいので、次のようなものを利用しますBar<Foo<>>

template <typename T = int> 
struct Foo {
  T t;
};

template <typename T>
struct Baz {
  T t;
};

template <typename T>
struct Bar;

template <template <typename> class T, typename X>
struct Bar<T<X>> {
  T<X> data;
  X x;
};

int main()
{
  Bar<Foo<>> a;
  Bar<Baz<float>> b;
}
于 2014-11-19T09:59:36.807 に答える
8
template <typename T> 
struct Foo {
  T t;
};

template <template <class> class T, class X>
struct Bar {
  T<X> data;
  X x;
};

int main()
{
  Bar<Foo, int> a;
}
于 2014-11-19T09:44:24.343 に答える
7

template <template <class X> class T>

テンプレート型パラメーターXは、最も外側のテンプレートに対するテンプレート パラメーターではありません。これは、最も内側のテンプレートに対するテンプレート パラメーターです。それはかなり似ています

int foo(int (*bar)(int x))
{
    int y = x;  // compiler error
}

関数は単一の引数を取るため、これは機能しませんbar: 引数がありませんx

本当に何をしようとしているかに応じて、次のような 2 番目のテンプレート パラメーターを追加できます。

template <typename X, template <typename> class T >
struct Bar
{
    // ...
};

単一の型パラメーターで宣言を保持できますが、パターン マッチにより、例のコンテキストでクラスを定義する部分的な特殊化が行われます。

template <typename T>
struct Bar;

template <typename X, template <typename> class T >
struct Bar<T<X>>
{
    // ...
};

便利なネストされた型を持つように変更Fooし、その方法でそれをつかむことができます

template <typename T>
struct Bar
{
    using X = T::value_type;
};

または、テンプレート型からテンプレート パラメータを抽出するメタ関数を定義して、その方法で取得することもできます。

template <typename T>
struct Bar
{
    using X = get_parameter<T>;
};

テンプレート引数を抽出するメタ関数ではなく、関数を宣言し、 (または)get_bar_parameterからテンプレート パラメーターを抽出する部分的な特殊化を定義することを除いて、最も柔軟なのは最後のバージョンです。そうすれば、 の正しい値がそのように計算されないクラスで使用することを将来決めた場合、 に適切な特殊化を与えることでそうすることができます。Foo<X>T<X>BarX get_bar_parameter

于 2014-11-19T14:43:21.613 に答える