ループ内の条件をチェックし、最初に満たされたときにコードのブロックを実行したいと思います。その後、ループが繰り返される可能性がありますが、ブロックは無視する必要があります。そのためのパターンはありますか?もちろん、ループの外側でフラグを宣言するのは簡単です。しかし、私は完全にループの中に住んでいるアプローチに興味があります。
この例は私が望むものではありません。ループの外側の定義を取り除く方法はありますか?
bool flag = true;
for (;;) {
if (someCondition() && flag) {
// code that runs only once
flag = false;
}
// code that runs every time
}
これはかなりハッキーですが、アプリケーションのメインループであるとおっしゃっていたように、これは1回限りの関数内にあると想定しているため、次のように機能するはずです。
struct RunOnce {
template <typename T>
RunOnce(T &&f) { f(); }
};
:::
while(true)
{
:::
static RunOnce a([]() { your_code });
:::
static RunOnce b([]() { more_once_only_code });
:::
}
メビウスの答えのそれほど複雑でないバージョンの場合:
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.
}
ブール値で++
を使用してこれを記述することもできますが、それは明らかに 非推奨 です。
これを書くためのおそらくよりクリーンな方法は、まだ変数がありますが、次のようになります
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.
}
このループを1回だけ実行することがわかっている場合は、ループの最後のステートメントとしてbreak
を使用してみませんか。