简体   繁体   English

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

[英]Correct usage of C++ template template parameters

I've some trouble to make use of template template parameters. 我在使用模板模板参数方面遇到了一些麻烦。 Here is a very simplified example: 这是一个非常简单的例子:

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

The compiler (g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2) reports the following error: 编译器(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;
      ^

Any idea what's wrong? 知道什么是错的吗?

So I would like so make use of something like Bar<Foo<>> 所以我想使用像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;
}
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;
}

In

template <template <class X> class T>

The template type parameter X is not a template parameter to the outermost template: it is a template parameter to the innermost template. 模板类型参数X不是最外层模板的模板参数:它是最里面模板的模板参数。 It's rather similar to 它非常相似

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

which doesn't work since the function takes a single argument, bar : there is no argument x . 由于函数只接受一个参数,因此不起作用, bar :没有参数x

Depending upon what you are truly trying to do, you could add the second template parameter, with something like 根据您真正想要做的事情,您可以添加第二个模板参数,例如

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

you can keep the declaration with a single type parameter, but pattern match to give a partial specialization that would define the class in the example context 您可以使用单个类型参数保留声明,但是模式匹配以提供将在示例上下文中定义类的部分特化

template <typename T>
struct Bar;

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

you could modify Foo to have a useful nested type, and grab it that way 你可以修改Foo以获得一个有用的嵌套类型,然后抓住它

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

or you could define a metafunction that extracts a template parameter from a template type, and get it that way: 或者您可以定义一个从模板类型中提取模板参数的元函数,并以此方式获取:

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

The most flexible is the last version, except rather than a metafunction that extracts template arguments, you would declare a get_bar_parameter function, and define a partial specialization that extracts the template parameter from a Foo<X> (or a T<X> ). 最灵活的是最后一个版本,除了提取模板参数的元函数之外,您将声明一个get_bar_parameter函数,并定义一个从Foo<X> (或T<X> )中提取模板参数的部分特化。 That way, if you ever decide in the future to use Bar with classes where the right value of X isn't computed that way, you can do so by giving an appropriate specialization for get_bar_parameter . 这样,如果您决定将来使用Bar ,其中X的正确值不是以这种方式计算的,那么您可以通过为get_bar_parameter提供适当的专门化来get_bar_parameter

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

In method 1 information is provided with nested type. 在方法1中,信息以嵌套类型提供。 This requires changing original class. 这需要改变原始类。

In method 2 this information is provided with specialization of another template. 在方法2中,该信息与另一个模板的专门化一起提供。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM