7

可変個引数テンプレートテンプレートに問題があります。

            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<A<int>> 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;
    }
4

2 に答える 2

2

スペシャライゼーションを使用して、一度に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
}
于 2012-11-16T14:18:46.607 に答える
1

このような :

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< int, float>もはやテンプレートではないため、機能しません(これは具象クラスです)。

于 2012-11-16T10:19:30.400 に答える