5

複雑な質問で申し訳ありませんが、基本的にアイデアは非常に単純です。可変個引数クラステンプレートがあります:

template<class P1, class P2, class ... P3s>
class A 
{
    ...
};

整数のテンプレートパラメーターNを受け取り、NP3sパラメーターを使用してAクラスをインスタンス化するAクラスジェネレーターが必要です。好き:

template<class P1, class P2, class P3, int N>
class GenA : /* somehow */ : public A<P1, P2, /* N times */ P3, P3, ...>
{
    ...
};

したがって、使用法は次のようになります。

// Generates A<Class1, Class2, Class3, Class3, Class3>
GenA<Class1, Class2, Class3, 3> a; 

私はすでにコンパイル時の再帰と部分的な特殊化でそれをやってみました

template <class P1, class P2, int N, class P3>
class GenA : public GenA<P1, P2, N-1, P3, P3>
{
    ...
}

template <class P1, class P2, int N, class ... P3s>
class GenA<P1, P2, 0, P3s ...> : public A<P1, P2, P3s, ...>
{
    ...
}

ただし、C ++ 11は、2番目のテンプレートが最初のテンプレートの特殊化であると認識せず(実際には異なるため)、再帰の基本ケースに到達することはありません(再帰レベルが多すぎると文句を言うのをやめます)。 。何か案は?

ありがとう
Tunnuz

4

2 に答える 2

5
template<class P1, class P2, class... P3s>
class A {};

template<class... Ps>
struct TypeList {};

template<class P1, class P2, class P3, unsigned N, class P> struct GenHelp;

template<class P1, class P2, class P3, class... Ps>
struct GenHelp<P1, P2, P3, 0, TypeList<Ps...> >
{
   typedef A<P1, P2, Ps... > AType;
};

template<class P1, class P2, class P3, unsigned N, class... Ps>
struct GenHelp<P1, P2, P3, N, TypeList<Ps...> > : public GenHelp<P1, P2, P3, N-1, TypeList<P3, Ps...> >
{};

template<class P1, class P2, class P3, unsigned N>
class GenA : public GenHelp<P1, P2, P3, N, TypeList<> >::AType
{};
于 2012-10-10T10:03:02.870 に答える
5

これを行うには、可変個引数テンプレートテンプレートパラメータを使用できます。この実装では P1、とで構成される引数パックから始めて、P3それを拡張し続けます。最後に、その引数パックを使用して可変個引数テンプレートテンプレートパラメーターをインスタンス化します。

template<class P1, class P2, class ... P3s>
struct A {};

template<template<class... Args> class AT, typename P3, int N, 
         typename... Already>
struct GenAImpl {
  typedef typename GenAImpl<AT, P3, N - 1, Already..., P3>::type type;
};

template<template<class... Args> class AT, typename P3, 
         typename... Already>
struct GenAImpl<AT, P3, 0, Already...> {
  typedef AT<Already...> type;
};


template<class P1, class P2, class P3, int N>
struct GenA : GenAImpl<A, P3, N, P1, P2>
{};

int main()
{
  GenA<int, double, float, 3>::type X;
  return 0;
}

リストに追加することはしばしば悪い考えであることに注意してください(少なくとも実際の関数型言語では、それが実際にC ++コンパイラのパフォーマンスに影響を与えるかどうかはわかりません)。

于 2012-10-10T10:08:48.440 に答える