在运行时生成可变参数列表

时间:2018-04-26 15:21:16

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

假设我想要处理N_DIMS维度的方形网格网格,每个N_RES个元素的长度都是N_ELEMS = std::pow(N_RES, N_DIMS)元素。

我必须遵循的实现是对非平方网格的推广

template<typename T, size_t... DIMS>
class MeshGrid
{
   // ... etc etc
}

例如,具有3维,分别为4,5,6个元素的可能实例可以是

 MeshGrid<float, 4, 5, 6> mg; // call A

现在我喜欢将它改编为像

这样的东西
template<typename T, size_t RES, size_t... DIMS>
class MeshSquare
{
   // ... etc etc
}

保留MeshGrid内部DIMS逻辑,以执行运行时调用,例如 B

int res = 4, dims = 2
MeshSquare<float, res, ??dims??> // call B

对于2维的方形网格示例,每个4个元素= 16个总元素。

我真的怀疑我想做什么;我觉得必须在编译时处理可变列表;上面的 B 电话是无稽之谈。

如果有可能,我的问题是如何扩展dims以适应 B 电话。

1 个答案:

答案 0 :(得分:1)

如果您需要在MeshSquare上对dims进行模板化,那么您在此处唯一可以做的就是提前生成所有实例化,然后在运行时生成switch。 E.g。

switch(dims)
{
    case 0: foo<MeshSquare<float, res, 0>>(); break;
    case 1: foo<MeshSquare<float, res, 0, 1>>(); break;
    case 2: foo<MeshSquare<float, res, 0, 1, 2>>(); break;
    case 3: foo<MeshSquare<float, res, 0, 1, 2, 3>>(); break;
    case 4: foo<MeshSquare<float, res, 0, 1, 2, 3, 4>>(); break;
    // ...
}

您可以使用C ++ 17折叠表达式,编译时递归和index_sequence以及许多其他技术轻松生成这些类型的开关。或者,考虑使用一个库作为运行时和编译时世界之间的桥梁,例如petra(C ++ 17)。

更合适的解决方案可能不是将维度存储为模板参数,而是使用更动态(运行时)的数据结构。