如何在不制作代码的 2 个版本的情况下切换代码的​​深层嵌套部分

How to make a deep nested part of code be toggled without making 2 versions of it

我的代码结构如下:

for
 for
  for
   for
    {
    things
    if(condition1||condition2)
    }

基本上“if”会检查 2 个依赖于它之前的每个循环的变量,但只有在用户在程序开始时这样说时才需要检查,否则“if”是没有意义的。

我可以使用 if(boolean&&(condition1||condition2)),它会很好用,除了它会在所有循环的每一次迭代中被检查。

所以我的问题是:如果用户这么说,有没有办法让 C++ 完全禁用“if”(不检查每个循环的条件),而不用和不重复 if???例如:

if(boolean)
 {
  all the fors
    things
    if(conditio1||condition2)
 }
else
 {
  all the fors
    things
 }

这很好用,但如果我以后必须做任何更改,我将不得不写两次,有可能忘记第二次或犯错误。我也有其他 3 部分代码有同样的问题,所以代码会变得很长。

编辑:你们中的一些人认为我们正在谈论微不足道的迭代次数,但在每个完整程序结束时,“如果”必须至少检查 1080 万次。正如我所说,我有(现在有 2 个)更多代码部分存在相同问题,因此可以节省相当多的时间。 太糟糕了 if constexpr 的解决方案使用了 C++17

将您的 for 循环移动到函数中并使用回调作为函数参数。

#include <iostream>

void func(void (*callback)(int i, int j)) {
  for (int i = 0; i < 100; i++) {
    for (int j = 0; j < 100; j++) {
      std::cout << "i = " << i << ", j = " << j << ", (i + j) % 3 == " << (i + j) % 3 << "\n";
      callback(i, j);
    }
  }
}

int main() {
  bool verbose = false;
  std::cin >> verbose;
  if (verbose) {
    func([](int i, int j){ if((i + j) % 3 == 0) std::cout << "Their sum is divided by three.\n" ; });
  }
  else {
    func([](int i, int j){});
  }
}

您可以在这样的函数中编写代码

template<bool Boolean>
void code(/* parameters */)
{
  for // ...
    for // ...
      // all the fors ...
      {
         // things 
         if constexpr (Boolean)  // compile time branch
         {
            if(condition1 || condition2)
               // ...
         }
      }
}

if constexpr只有在Boolean为真时才会被编译。所以在调用站点你可以做

bool boolean = /* some run-time initialization */
if (boolean)
  code<true>(/* arguments */);
else 
  code<false>(/* arguments */);

请注意,这不是为了性能而应该做的事情,除非您已经测量和分析代码以查看它是否是瓶颈。完成后,您可以使用上述技术。


如果您还没有使用 C++17,整个 if constexpr 块可以替换为

work<Boolean>(/* arguments */);

其中 work 是专门用于仅在 true 情况下工作的函数模板:

template<bool>
void work(/* parameters */) {}  

template<>
void work<true>(/* parameters */) 
{
  if(condition1 || condition2)
     // ...
}