如何在while循环中处理多个相似条件?

How to handle multiple similar conditions in while loop?

抱歉标题不是那么难以捉摸,但这是我将用来解释我的问题的一段代码!

while(motors[0].cycle <= maxcycle
   && motors[1].cycle <= maxcycle
   && motors[2].cycle <= maxcycle
   && motors[3].cycle <= maxcycle
   && motors[4], etc ...)

如何避免为我的 while() 循环输入这么长的条件,因为我总是检查相同的参数,只有结构的索引在变化。

How can I avoid typing this very long conditions, knowing that I'm always checking the same parameter, only the index of my structure is changing.

添加一个函数来进行检查并在 while 语句中使用该函数。

// MotorType is my contrived type. Use the right type.
bool doCheck(MotorType* motors, int count, int maxcycle)
{
   for (int i = 0; i < count; ++i )
   {
      if ( !(motors[0].cycle <= maxcycle) )
      {
         return false;
      }
   }
   return true;
}

while(doCheck(motors, count, maxcycle))
{
}

将条件抽象成方法。

while ( allMotorsLessThanMax( motors, countMotors )) {
 ...
}

然后用自己的迭代定义该方法:

bool allMotorsLessThanMax( Motor motors[], int countMotors ) {
   for ( int i = 0; i < countMotors; ++i ) {
     if ( maxcycle < motors[i].cycle ) {
         return false;
     }
  } 
  return true;
}

将其分解为一个单独的函数并在单独的函数中遍历数组,return如果它没有通过 if 检查,则一直为真或为假。

你可以循环执行:

while(true)
{
  for(int i = 0, i < number, i++)
  {
    if (motors[i].cycle > maxcycle)
    {
      break;
    }
  }
  //Do something
}

这里所有建议加法函数的答案都可以做到...好吧,不一定是最好的方法。原因如下:

由于循环被放入单独的函数中,并且 motors 的数量不是常数,编译器很可能会使用真正的循环并且不会展开它。当您计算纳秒时,自然循环是一种性能危害。 但是,原始示例没有这个问题,因为它根本没有循环。

解决方案:提供一个完全不使用循环的函数,或者让编译器更容易展开它。

将其放入 lambda 的支票中:

#include <algorithm>

...
void myFunction(){

    auto allCycling = [&]() -> bool { // lambda function, capture by reference
        return std::all_of( // for every element in the given range
          motors.begin(), motors.end(), // given range is all of the motors container
          [](const decltype(motors[0])& motor) -> bool {
            return motor.cycle <= maxcycle; // check
          });

    while(allCycling()){
        //do stuff
    }
}

lambda 的引用捕获 [&] 允许您访问 lambda 中所有函数范围的变量,而无需担心复制它们的成本。

C++11 及更高版本允许您使用 lambda:

将自定义检查函数折叠到 std::all_of 的调用中
while (std::all_of(std::begin(motors), std::end(motors),
                   [=](Motor m){ return m.cycle < maxcycle; })) 
{
    ...

Demo

我来折腾TMP版本:

template < size_t I >
struct check_it
{
    static bool call(motor_type * motors)
    {
       return check_it<I-1>::call(motors) && motors[I].cycles <= maxcycles;
    }
 }

 template < >
 struct check_it<0>
 {
     static bool call(motor_type * motors) { return motors[0].cycles <= maxcycles; }
 };

 while (check_it<42>::call(motors)) { ... }

编辑:我不一定推荐这个,但它应该根据你写的内容进行优化。很难说它是否真的更快。将取决于缓存中有多少指令等......也许吧?如果它很重要,你会想要分析。