C++ 中非类型模板的预处理与模板化

问题描述 投票:0回答:1

我有一个 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 个空间维度。

c++ templates preprocessor
1个回答
0
投票

我看到有两种方法可以使用更高级别的抽象来做到这一点。

首先,循环本身可以变成范围。 其次,手术可以变成程序。

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);

最终目标是编译后的代码与您手写的循环相同。

© www.soinside.com 2019 - 2024. All rights reserved.