danijar
danijar

Reputation: 34215

How to run code inside a loop only once without external flag?

I want to check a condition inside a loop and execute a block of code when it's first met. After that, the loop might repeat but the block should be ignored. Is there a pattern for that? Of course it's easy to declare a flag outside of the loop. But I I'm interested in an approach that completely lives inside the loop.

This example is not what I want. Is there a way to get rid of the definition outside of the loop?

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

Upvotes: 14

Views: 45690

Answers (6)

#include <iostream>
using namespace std;

int main()
{
    int fav_num = 0;

    while (true)
    {
    if ( fav_num == 0)
    {
        cout <<"This will only run if variable fav_number is = 0!"<<endl;
    }
    cout <<"Please give me your favorite number."<<endl;
    cout <<"Enter Here: ";
    cin >>fav_num;
    cout <<"Now the value of variable fav_num is equal to "<<fav_num<<" and not 0 so, the if statement above won't run again."<<endl;
    }
    
    return 0;
}

OUTPUT

This will only run if variable fav_number is = 0!

Please give me your favorite number.

Enter Here: 1

Now the value of variable fav_num is equal to 1 and not 0 so, the "if statement" above won't run again.

Upvotes: 0

Alec Jacobson
Alec Jacobson

Reputation: 6264

For a less convoluted version of Mobius's answer:

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.
}

You could also write this using ++ on a bool, but that's apparently deprecated .

Upvotes: 12

Mobius
Mobius

Reputation: 2896

a possibly cleaner way to write this, albeit still with a variable, would be as follows

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.
 }

The static allows you to declare the variable inside the loop, which IMHO looks cleaner. If your code that executes every time makes some testable change, you could get rid of the variable and write it like this:

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.
 }

Upvotes: 3

Meg
Meg

Reputation: 1

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    }

If you expecting the code without any external flag then you need to change the value of condition in last statement of the condition. (7th line in code snippet)

Upvotes: -2

Guanxi
Guanxi

Reputation: 3131

If you know you only want to run this loop once, why not use break as the last statement in the loop.

Upvotes: -1

It's fairly hacky, but as you said it's the application main loop, I assume it's in a called-once function, so the following should work:

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

:::

while(true)
{
  :::

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

  :::

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

  :::
}

Upvotes: 14

Related Questions