是否可以定义一个 C++11 可变参数类模板,其可变参数基数取决于整数模板参数
Is it possible to define a C++11 variadic class template whose variadic parameter cardinality depends on an integer template parameter?
很抱歉这个问题很复杂,但基本上这个想法非常简单。我有一个可变参数类模板:
template<class P1, class P2, class ... P3s>
class A
{
...
};
我想要一个 A 类生成器,它采用整数模板参数 N 并使用 N 个 P3s 参数实例化一个 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 不承认第二个模板是第一个模板的专用化(因为它实际上是不同的),并且永远不会到达递归的基本情况(它不再抱怨太多的递归级别)。有什么想法吗?
谢谢
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
{};
您可以使用可变参数模板模板参数来执行此操作。在此实现我们只需从一个参数包开始,其中包含 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++编译器性能),并且您最好将其组合在一起并在最后反转。
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)