Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在没有外部标志的情况下只在循环内运行一次代码?_C++_Loops_Design Patterns_Flags_Control Flow - Fatal编程技术网

C++ 如何在没有外部标志的情况下只在循环内运行一次代码?

C++ 如何在没有外部标志的情况下只在循环内运行一次代码?,c++,loops,design-patterns,flags,control-flow,C++,Loops,Design Patterns,Flags,Control Flow,我想检查循环中的一个条件,并在第一次遇到它时执行一段代码。之后,循环可能会重复,但块应该被忽略。有这样的模式吗?当然,在循环之外声明标志很容易。但我感兴趣的是一种完全活在循环中的方法 这个例子不是我想要的。有没有办法摆脱循环之外的定义 bool flag = true; for (;;) { if (someCondition() && flag) { // code that runs only once flag = false;

我想检查循环中的一个条件,并在第一次遇到它时执行一段代码。之后,循环可能会重复,但块应该被忽略。有这样的模式吗?当然,在循环之外声明标志很容易。但我感兴趣的是一种完全活在循环中的方法

这个例子不是我想要的。有没有办法摆脱循环之外的定义

bool flag = true;
for (;;) {
    if (someCondition() && flag) {
        // code that runs only once
        flag = false;
    }        
    // code that runs every time
}

它相当粗糙,但正如您所说的,它是应用程序主循环,我假设它位于一个调用一次的函数中,因此以下应该可以工作:

struct RunOnce {
  template <typename T>
  RunOnce(T &&f) { f(); }
};

:::

while(true)
{
  :::

  static RunOnce a([]() { your_code });

  :::

  static RunOnce b([]() { more_once_only_code });

  :::
}
struct RunOnce{
模板
跳动(T&&f){f();}
};
:::
while(true)
{
:::
静态RunOnce a([](){your_code});
:::
静态跳动b([](){more_once_only_code});
:::
}

一种可能更简洁的编写方法,尽管仍然使用变量,如下所示

while(true){
   static uint64_t c;
   // some code that executes every time
   if(c++ == 0){
      // some code that executes only once
   }
   // some more code that executes every time.
 }
static
允许您在循环内声明变量,IMHO看起来更干净。如果每次执行的代码都进行了一些可测试的更改,则可以去掉该变量并按如下方式编写:

while(true){
   // some code that executes every time
   if(STATE_YOUR_LOOP_CHANGES == INITIAL_STATE){
      // some code that executes only once
   }
   // some more code that executes every time.
 }

如果您知道只想运行此循环一次,为什么不使用
break
作为循环中的最后一条语句呢

1    while(true)
2    {
3        if(someCondition())
4        {
5            // code that runs only once
6            // ...
7          // Should change the value so that this condition must return false from next execution.
8        }        
9    
10        // code that runs every time
11        // ...
12    }

如果希望代码没有任何外部标志,则需要在条件的最后一条语句中更改条件的值。(代码片段中的第7行)

对于Mobius答案的不太复杂的版本:

while(true)
{
  // some code that executes every time
  for(static bool first = true;first;first=false)
  {
    // some code that executes only once
  }
  // some more code that executes every time.
}

您也可以在bool上使用
++
编写此代码,但显然是这样。

为什么不将该代码移出循环?我不认为如实使用标志有什么问题。如果我不想这样做,我就把它移到别处。假设“移出循环”不是你想要的,你怎么知道什么应该只执行一次,什么时候执行?@Sharptoth循环是一个应用程序循环,所以它一直在运行。使用异步线程对此来说太难了。@Matsson我只想在第一次到达给定的代码块时执行一次代码块。这可能是循环的第一次迭代,但由于其他条件的限制,它也可能是以后的循环。如果
c
超过
short
的边界,它不会不断增加,然后循环,某个时候又变为0吗?明白了吗。上面的注释是正确的,在下面的代码块中递增
c
更聪明。此外,布尔标志也会起作用。是的,我包括了计数器变量,因为它在一般情况下可能更有用。@Mobius我认为不是,因为每次迭代不可能只到达一次代码块。所以计数器变量不代表循环计数。如果您担心包装,为什么不使用64位int?在我的笔记本电脑上进行的一个快速测试表明,仅仅数到1.8e19(64位整数的最大值)需要大约1000年的时间。这正是我想要的。在执行lambda之后,我们可以销毁构造函数中的实例吗?@danijar否,它具有静态存储持续时间,因此它将在程序关闭时被销毁。问题是你为什么要这么做。请注意,lambda并没有存储在struct中,只是被执行和遗忘(即它被破坏)。struct实例本身可能只占用1-4个字节,这取决于您的编译器,而不需要对它们进行任何处理。好的,它不会感觉如此粗糙。请阅读问题下面的注释。例如,如果玩家级别超过给定的数字,他应该获得一次奖励。我不能为了不上两次奖就降低球员级别<代码>而(1){如果(级别>7){一次([=]{award();});}请再次阅读问题下的注释,因为第一个问题是,如果不使用标志如何实现,那么他只考虑下一个选项。标志是
之前的布尔变量,而
循环还是条件函数中的另一个标志,这有什么关系?这里我没有提到关于标志,因为我不想创建任何新的变量或标志(可重用性概念)。通过使用条件值,我们可以对其进行操作。请验证我的代码。