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: there is no argument x

根据您真正想要做的事情,您可以添加第二个模板参数,例如

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函数,并定义一个从 a Foo<X>(或 a T<X>)中提取模板参数的部分特化。这样,如果您将来决定与Bar以这种方式计算正确值的类一起使用,您可以通过为.X get_bar_parameter

于 2014-11-19T14:43:21.613 回答
0
// method 1
template <typename T> 
struct Foo {
  typedef T Type;
  T t;
};

template <typename T>
struct Bar {
  T data;
  typename T::Type x;
};

// method 2
template <typename T>
struct Hack
{
  T t;
};

template <typename T>
struct TypeOf
{
  typedef struct UnknownType Type;
};

template<>
struct TypeOf< Hack<int> >
{
  typedef int Type;
};

template <typename T>
struct Baz {
  T data;
  typename TypeOf<T>::Type X;
};

int main()
{
  Bar< Foo<int> > a;
  Baz< Hack<int> > b;
  return 0;
}

在方法 1 中,信息以嵌套类型提供。这需要改变原来的类。

在方法 2 中,此信息与另一个模板的特化一起提供。

于 2014-11-19T14:45:56.950 回答