我有一个 C++ 函数,它执行两次相同计算的嵌套 for 循环,每个嵌套 for 循环作用于不同的数据,并且作用于略有不同的数组/循环索引,但从概念上讲,它们正在做相同的事情。只需编写第一个嵌套 for 循环一次,然后让编译器复制它,重新创建嵌套循环并换出适当的变量和索引,这将为我节省大量编码/调试时间。这是一个虚拟示例。
void function(myStruct &b){
// first nested for loop
for(int i=0; i < 10; i++){
for(int j=0; j < 9, j++){
b.iF[i,j] = b.someOtherArray[i-1,j]*2;
}
}
// second nested for loop I do not want to code
for(int i=0; i < 9; i++){
for(int j=0; j < 10, j++){
b.jF[i,j] = b.someOtherArray[i,j-1]*2;
}
}
}
第二个嵌套 for 循环与第一个相同,但为“b.iF-->b.jF”、“i-1,j-->i,j-1”等。除此之外,他们也做同样的事情。我从未使用过模板,但这似乎不是模板的正确使用,因为没有类型差异。定义宏将涉及将嵌套循环的“内容”编写为宏,这不太可读。不确定这是否是正确的阅读,或者是否有一些我不知道的事情,这将是一个很好的解决方案。
我可以将每个嵌套循环分解为一个单独的函数,并使用正确的变量和索引作为参数来调用它们,但我想尝试一些不同的东西。
真正的用例是从 1 维物理问题到 3 维问题,其中我在其他 2 空间维度中再重复 1D 物理两次。因此,最好只编写一维情况,然后让编译器为我重复其他 2 个空间维度。
我看到有两种方法可以使用更高级别的抽象来做到这一点。
首先,循环本身可以变成范围。 其次,手术可以变成程序。
void function(myStruct& b){
auto body = [&](int i0, int j0, int i1, int j1) {
b.iF[i0,j0] = b.someOtherArray[i1,j1]*2;
};
auto range1 = range(0, 10);
auto range2 = range(0, 9);
(range1 * range2)([&](auto i, auto j){
body(i,j,i-1,j);
});
(range2 * range1)([&](auto i, auto j){
body(i,j,i,j-1);
});
}
这里我有范围类型,允许对其进行操作并接受函数对象。 这试图删除结构编码(for 循环、维护结束电位等)并使其成为数据。
我重写了主体,以便输入和输出参数是不同的。 然后我编写一个 lambda 包装器来做出决定。 你可以用 i,j 和 delta_i 和 delta_j 代替。
body(i,j,0,-1);
最终目标是编译后的代码与您手写的循环相同。