正确使用C++模板模板参数

Tho*_* W. 11 c++ templates template-templates

我在使用模板模板参数方面遇到了一些麻烦.这是一个非常简单的例子:

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;
}
Run Code Online (Sandbox Code Playgroud)

编译器(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;
      ^
Run Code Online (Sandbox Code Playgroud)

知道什么是错的吗?

Pio*_*cki 9

所以我想这样使用类似的东西 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;
}
Run Code Online (Sandbox Code Playgroud)

  • @ThomasWitkowski 它是*主要模板*,这样我就可以将它专门用于 `struct Bar&lt;T&lt;X&gt; &gt;` 情况。故意使其不完整,以便不使用单参数模板以外的类型实例化它 (2认同)

Jok*_*_vD 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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Bathsheba可能是因为我没有留下任何解释.但对我来说这太奇怪了,我不能把它用英语单词. (3认同)

小智 5

template <template <class X> class T>
Run Code Online (Sandbox Code Playgroud)

模板类型参数X不是最外面的模板的模板参数:它是最里面的模板的模板参数。相当类似于

int foo(int (*bar)(int x))
{
    int y = x;  // compiler error
}
Run Code Online (Sandbox Code Playgroud)

由于函数只接受一个参数,因此不起作用bar:没有论点x

根据您的实际尝试,可以添加第二个模板参数,例如

template <typename X, template <typename> class T >
struct Bar
{
    // ...
};
Run Code Online (Sandbox Code Playgroud)

您可以使用单个类型参数保留声明,但可以通过模式匹配来提供部分特殊化,以在示例上下文中定义类

template <typename T>
struct Bar;

template <typename X, template <typename> class T >
struct Bar<T<X>>
{
    // ...
};
Run Code Online (Sandbox Code Playgroud)

您可以修改Foo为具有有用的嵌套类型,然后以这种方式获取它

template <typename T>
struct Bar
{
    using X = T::value_type;
};
Run Code Online (Sandbox Code Playgroud)

或者您可以定义一个从模板类型中提取模板参数的元函数,并通过以下方式获取它:

template <typename T>
struct Bar
{
    using X = get_parameter<T>;
};
Run Code Online (Sandbox Code Playgroud)

最灵活的是最后一个版本,除了不是提取模板参数的元函数,您将声明一个get_bar_parameter函数,并定义一个部分特化,该部分特化从Foo<X>(或T<X>)提取模板参数。这样一来,如果您将来决定使用不能以这种方式计算Bar正确值的类,则可以通过给适当的专门化来实现。X get_bar_parameter