32 Thread support library [thread]

32.5 Mutual exclusion [thread.mutex]

32.5.6 Call once [thread.once]

32.5.6.2 Function call_­once [thread.once.callonce]

template<class Callable, class... Args> void call_once(once_flag& flag, Callable&& func, Args&&... args);
Mandates: is_­invocable_­v<Callable, Args...> is true.
Effects: An execution of call_­once that does not call its func is a passive execution.
An execution of call_­once that calls its func is an active execution.
An active execution calls INVOKE(​std​::​forward<Callable>(func), std​::​forward<Args>(args)...).
If such a call to func throws an exception the execution is exceptional, otherwise it is returning.
An exceptional execution propagates the exception to the caller of call_­once.
Among all executions of call_­once for any given once_­flag: at most one is a returning execution; if there is a returning execution, it is the last active execution; and there are passive executions only if there is a returning execution.
[Note
:
Passive executions allow other threads to reliably observe the results produced by the earlier returning execution.
— end note
]
Synchronization: For any given once_­flag: all active executions occur in a total order; completion of an active execution synchronizes with the start of the next one in this total order; and the returning execution synchronizes with the return from all passive executions.
Throws: system_­error when an exception is required ([thread.req.exception]), or any exception thrown by func.
[Example
:
// global flag, regular function
void init();
std::once_flag flag;

void f() {
  std::call_once(flag, init);
}

// function static flag, function object
struct initializer {
  void operator()();
};

void g() {
  static std::once_flag flag2;
  std::call_once(flag2, initializer());
}

// object flag, member function
class information {
  std::once_flag verified;
  void verifier();
public:
  void verify() { std::call_once(verified, &information::verifier, *this); }
};
— end example
]