std::call_once

From cppreference.com
< cpp‎ | thread
Defined in header <mutex>
template< class Callable, class... Args >
void call_once( std::once_flag& flag, Callable&& f, Args&&... args );
(since C++11)

Executes the Callable object f exactly once, even if called from several threads.

Each group of call_once invocations that receives the same std::once_flag object will meet the following requirements:

  • Exactly one execution of exactly one of the functions (passed as f to the invocations in the group) is performed. It is undefined which function will be selected for execution. The selected function runs in the same thread as the call_once invocation it was passed to.
  • No invocation in the group returns before the above-mentioned execution of the selected function is completed successfully, that is, doesn't exit via an exception.
  • If the selected function exits via exception, it is propagated to the caller. Another function is then selected and executed.

Parameters

flag - an object, for which exactly one function gets executed
f - Callable object to invoke
args... - arguments to pass to the function

Return value

(none)

Exceptions

  • std::system_error if any condition prevents calls to call_once from executing as specified
  • any exception thrown by f

Notes

The arguments to the Callable object are moved or copied by value. If a reference argument needs to be passed to the Callable object, it has to be wrapped (e.g. with std::ref or std::cref).

(until C++17)

The arguments to the Callable object are perfect forwarded (as if by std::forward<Callable>(f) and std::forward<Args>(args))...), which is different from the uses of Callables in the thread constructor or std::async, because call_once does not have to transfer its arguments to another thread of execution, and therefore does not need to move or copy.

(since C++17)

Initialization of function-local statics is guaranteed to occur only once even when called from multiple threads, and may be more efficient than the equivalent code using std::call_once.