Use std::exchange
:
if (static bool do_once = true; std::exchange(do_once, false))
You can make it shorter reversing the truth value:
if (static bool do_once; !std::exchange(do_once, true))
But if you are using this a lot, don’t be fancy and create a wrapper instead:
struct Once {
bool b = true;
explicit operator bool() { return std::exchange(b, false); }
};
And use it like:
if (static Once once; once)
The variable is not supposed to be referenced outside the condition, so the name does not buy us much. Taking inspiration from other languages like Python which give a special meaning to the _
identifier, we may write:
if (static Once _; _)
Further improvements: take advantage of the BSS section (@Deduplicator), avoid the memory write when we have already run (@ShadowRanger), and give a branch prediction hint if you are going to test many times (e.g. like in the question):
// GCC, Clang, icc only; use [[likely]] in C++20 instead
#define likely(x) __builtin_expect(!!(x), 1)
struct Once {
bool b = false;
explicit operator bool()
{
if (likely(b))
return false;
b = true;
return true;
}
};