tun*_*nuz 5 c++ templates c++11
抱歉这个令人费解的问题,但基本上这个想法非常简单.我有一个可变的类模板:
template<class P1, class P2, class ... P3s>
class A
{
...
};
Run Code Online (Sandbox Code Playgroud)
我想有一个A类生成器,它接受一个整数模板参数N并实例化一个带有N个P3参数的A类.喜欢:
template<class P1, class P2, class P3, int N>
class GenA : /* somehow */ : public A<P1, P2, /* N times */ P3, P3, ...>
{
...
};
Run Code Online (Sandbox Code Playgroud)
所以用法是:
// Generates A<Class1, Class2, Class3, Class3, Class3>
GenA<Class1, Class2, Class3, 3> a;
Run Code Online (Sandbox Code Playgroud)
我已经尝试过使用编译时递归和部分特化
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, ...>
{
...
}
Run Code Online (Sandbox Code Playgroud)
但是C++ 11不能识别第二个模板是第一个模板的特化(因为它实际上是不同的)并且永远不会到达递归的基本情况(它停止抱怨过多的递归级别) .有任何想法吗?
谢谢
Tunnuz
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
{};
Run Code Online (Sandbox Code Playgroud)
您可以使用可变参数模板模板参数来执行此操作.在这个实现中,我们只是从一个由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;
}
Run Code Online (Sandbox Code Playgroud)
请记住,附加到列表通常是一个坏主意(至少在实际的函数式语言中,我不知道这是否真的会影响C++编译器的性能)并且你最好将它集中在一起并在最后反转它.
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |