I have an application which has several functions in it. Each function can be called many times based on user input. However I need to execute a small segment of the code wi
Additionally to @Basile's answer, you can use a lambda to encapsulate the static variable as follows:
if ([] {
static bool is_first_time = true;
auto was_first_time = is_first_time;
is_first_time = false;
return was_first_time; } ())
{
// do the initialization part
}
This makes it easy to convert into a general-purpose macro:
#define FIRST_TIME_HERE ([] { \
static bool is_first_time = true; \
auto was_first_time = is_first_time; \
is_first_time = false; \
return was_first_time; } ())
Which can be placed anywhere you want call-by-need:
if (FIRST_TIME_HERE) {
// do the initialization part
}
And for good measure, atomics shorten the expression and make it thread-safe:
#include <atomic>
#define FIRST_TIME_HERE ([] { \
static std::atomic<bool> first_time(true); \
return first_time.exchange(false); } ())
As of C++11, static local variables are thread-safe and usually sufficient for most cases, so std::call_once()
et al. very well may be overkill.
This looks especially elegant when using C++17's initialisation-within-if
and std::exchange():
#include <utility>
void
do_something_expensive_once()
{
if ( static auto called = false; !std::exchange(called, true) ) {
do_something_expensive();
}
}
If this is a pattern you use a lot, then we can encapsulate it via a tag type:
#include <iostream>
#include <utility>
template <typename T>
auto
call_once()
{
static auto called = false;
return !std::exchange(called, true);
}
void
do_something_expensive()
{
std::cout << "something expensive\n";
}
void
do_something_expensive_once()
{
if ( call_once<struct TagForSomethingExpensive>() ) {
do_something_expensive();
}
}
auto
main() -> int
{
for (auto i = 0; i < 5; ++i) {
do_something_expensive_once();
}
return 0;
}
This will only print something expensive
a single time. Result! It also uses the ability to declare a tag struct
in a template argument list, for maximal brevity.
Alternatively, you could template on a function's address, a unique integer, etc.
You can then also pass a callable to call_once()
, and so on, and so forth. As usual for C++: the possibilities are endless!
Use global static objects with constructors (which are called before main
)? Or just inside a routine
static bool initialized;
if (!initialized) {
initialized = true;
// do the initialization part
}
There are very few cases when this is not fast enough!
In multithreaded context this might not be enough:
You may also be interested in pthread_once or constructor function __attribute__ of GCC.
With C++11, you may want std::call_once.
You may want to use <atomic> and perhaps declare static volatile std::atomic_bool initialized;
(but you need to be careful) if your function can be called from several threads.
But these might not be available on your system; they are available on Linux!
Compact version using lambda function:
void foo()
{
static bool once = [](){
cout << "once" << endl;
return true;
} ();
cout << "foo" << endl;
}
Code within lambda function is executed only once, when the static variable is initialized to the return value of lambda function. It should be thread-safe as long as your compiler support thread-safe static initialization.
Using C++11 -- use the std::call_once
#include <mutex>
std::once_flag onceFlag;
{
....
std::call_once ( onceFlag, [ ]{ /* my code body here runs only once */ } );
....
}
You can use local static variable:
void foo()
{
static bool wasExecuted = false;
if (wasExecuted)
return;
wasExecuted = true;
...
}