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

3

假设我想处理N_DIMS维的正方形网格,每个边长为N_RES元素,这将产生N_ELEMS = std::pow(N_RES, N_DIMS)个元素。

我需要遵循的实现是非正方形网格的泛化。

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

例如,一个可能的实例包含三个维度,分别有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调用。


9
你的感觉没错:你无法在运行时生成模板实例化。 - Quentin
1
是的,所有模板都在编译时解析。 - Gem Taylor
1个回答

1
如果你需要将 MeshSquare 模板化为 dims,那么你能在这里做的唯一一件事就是预先生成所有实例,然后在运行时使用 switch。例如:
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)。
一个更合适的解决方案可能是不将维度存储为模板参数,而是使用更动态(运行时)的数据结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接