【问题标题】:template template syntax problems with variadic templates可变参数模板的模板模板语法问题
【发布时间】:2012-11-05 01:03:29
【问题描述】:

我对可变参数模板模板有疑问:

            template <typename T> class A { };
            template< template <typename> class T> class B { };
            template <template <typename> class T, typename parm> class C { typedef T<parm> type; };
            template <typename... types> class D { };
            template <template <typename...> class T, typename ... parms> class E { typedef T<parms...> type; };

            // How to pass list in list??
            template < template <typename...> class ...T, ???>
            class F
            {
            };

首先,给模板传一个类型,没问题:

            A<int> a; //ok

现在,我想从 B 创建一个实例,但是没有办法传递模板模板参数:

            B<A> b; // ok, but no chance to submit <int> inside A!

所以我必须扩展参数列表:

            C<A, int> c; // ok, this transport int as parm into A

现在我以标准方式使用可变参数模板:

            D<> d1; // ok
            D<int, float, double> d2;   //ok

将参数传递到可变参数部分也很困难:

            E<D> e1;    //ok
            E<D, double, float, int> e2; //ok

但是:如果我想要一个列表列表,我找不到可以通过的语法 参数列表到类型列表。我的意图是这样的。而且上面的例子也表明B&lt;A&lt;int&gt;&gt; b; 是一个错误!所以下面的例子不能工作:-(

            F< D< int, float>, D< int>, D <float, float, float> > f;

我的目标是通过模板专业化展开列表列表。有什么提示吗?

我理解问题后的解决方案。谢谢!

现在我可以展开我的可变参数模板模板,如下例所示。简单的问题是,我等待模板类而不是简单类型。有时,解决方案可以很简单:-)

这就是我现在的工作结果:

    template <typename ... > class D;

    template <typename Head, typename... types>
    class D<Head, types...>
    {
       public:
          static void Do() { cout << "AnyType" << endl; D<types...>::Do(); }
    };

    template<>
    class D<>
    {
       public:
          static void Do() { cout << "End of D" << endl; }
    };

    template < typename ...T> class H;

    template < typename Head, typename ...T>
    class H<Head, T...>
    {
       public:
          static void Do()
          {
             cout << "unroll H" << endl;
             cout << "Subtype " << endl;
             Head::Do();
             H<T...>::Do();
          }
    };

    template <>
    class H<>
    {
       public:
          static void Do() { cout << "End of H" << endl; }
    };


    int main()
    {
       H< D<int,int,int>, D<float, double, int> >::Do();
       return 0;
    }

【问题讨论】:

    标签: c++ templates c++11 variadic-templates


    【解决方案1】:

    您可以通过专业化一次解压一个可变参数专业化:

    template<typename...> struct S;
    template<> struct S<> { constexpr static int n = 0; };
    template<template<typename...> class T, typename... Us, typename... Vs>
    struct S<T<Us...>, Vs...> {
        constexpr static int n = sizeof...(Us) + S<Vs...>::n;
    };
    
    template<typename...> struct D {};
    
    #include <iostream>
    int main() {
        std::cout << S<D<int, int, int>, D<int, int>, D<int>>::n << '\n'; // prints 6
    }
    

    【讨论】:

    • 谢谢,你的回答让我大开眼界。我对我的问题提出了最终解决方案。希望这对其他人有帮助。
    【解决方案2】:

    像这样:

    template < template <typename...> class ...T >
    class F
    {
    };
    int main()
    {
      F< D, D > f;
    }
    

    所以,F 期望的是一个可变参数模板类,它接受另一个可变参数模板类作为它的参数。

    您不能扩展模板类参数的参数。如果您专门化您作为参数传递的模板类,那么您将获得专门化的版本。

    这个:

     F< D< int, float>, D< int>, D <float, float, float> > f;
    

    不起作用,因为 F 需要可变参数模板类,将可变参数模板类作为类型,而 D&lt; int, float&gt; 不再是模板(它是一个具体的类)。

    【讨论】:

    • 你描述的和我在B&lt;A&gt; b;的代码一样。我的问题是关于获取列表列表,这意味着有可以扩展的参数。真的不可能使用列表列表吗?我不会相信:-)
    • @Klaus 你写道:no chance to submit &lt;int&gt; inside A!。您可以在 A 中执行此 typedef A type 并在 B 中将其用作 typename A::type,但您不能在可变参数模板中执行此操作(不能这样做:typedef typename... types
    • 似乎我走错了路,可变参数模板模板不是解决方案。有没有其他方法可以获得所需的功能?很容易获得一个可以通过专业化扩展的列表。我仍然希望也有一种方法来处理这些事情,还有一个列表。欢迎任何提示!你能给我一个工作例子来说明你在上一条评论中的意思吗?
    • @Klaus 实际上,评论的最后一部分是垃圾。你需要知道B中的类型,因为它的模板参数是一个模板类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2014-09-08
    • 2014-04-12
    • 2013-09-14
    相关资源
    最近更新 更多