我有一个整数N我在编译时就知道了。我也有一个标准::数组保存描述形状的整数N维数组。我想在编译时使用元编程技术生成嵌套循环,如下所述。
constexpr int N {4};
constexpr std::array<int, N> shape {{1,3,5,2}};
auto f = [/* accept object which uses coords */] (auto... coords) {
// do sth with coords
};
// This is what I want to generate.
for(int i = 0; i < shape[0]; i++) {
for(int j = 0; j < shape[1]; j++) {
for(int k = 0; k < shape[2]; k++) {
for(int l = 0; l < shape[3]; l++) {
f(i,j,k,l) // object is modified via the lambda function.
}
}
}
}
注意参数N在编译时已知,但在编译之间可能会发生不可预测的变化,因此我无法像上面那样对循环进行硬编码。理想情况下,循环生成机制将提供一个接口,该接口接受 lambda 函数、生成循环并调用生成上述等效代码的函数。我知道可以在运行时用一个 while 循环和一个索引数组编写一个等效的循环,并且这个问题已经有了答案。然而,我对这个解决方案不感兴趣。我对涉及预处理器魔法的解决方案也不感兴趣。
像这样的东西(注意:我将“形状”作为可变参数模板参数集..)
#include <iostream>
template <int I, int ...N>
struct Looper{
template <typename F, typename ...X>
constexpr void operator()(F& f, X... x) {
for (int i = 0; i < I; ++i) {
Looper<N...>()(f, x..., i);
}
}
};
template <int I>
struct Looper<I>{
template <typename F, typename ...X>
constexpr void operator()(F& f, X... x) {
for (int i = 0; i < I; ++i) {
f(x..., i);
}
}
};
int main()
{
int v = 0;
auto f = [&](int i, int j, int k, int l) {
v += i + j + k + l;
};
Looper<1, 3, 5, 2>()(f);
auto g = [&](int i) {
v += i;
};
Looper<5>()(g);
std::cout << v << std::endl;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)