DelayedInit ‐‐ thread‐safe delayed initialization of a value. There are two important differences between Lazy and DelayedInit: 1. DelayedInit does not store the factory function inline. 2. DelayedInit is thread‐safe.

Synopsis

Declared in <folly/synchronization/DelayedInit.h>

template<typename T>
struct DelayedInit;

Description

Due to these differences, DelayedInit is suitable for data members. Lazy is best for local stack variables.

Example Usage:

struct Foo { Bar& bar() { LargeState state; return bar_.try_emplace_with( [this, &state]{ return computeBar(state); }); } private: Bar computeBar(LargeState&); DelayedInit<Bar> bar_; };

If the above example were to use Lazy instead of DelayedInit:

  • Storage for LargeState and this‐pointer would need to be reserved in the struct which wastes memory.

  • It would require additional synchronization logic for thread‐safety.

Rationale:

  • The stored value is initialized at most once and never deinitialized. Unlike Lazy, the initialization logic must be provided by the consumer. This means that DelayedInit is more of a "storage" type like std::optional. These semantics are perfect for thread‐safe, lazy initialization of a data member.

  • DelayedInit models neither MoveConstructible nor CopyConstructible. The rationale is the same as that of std::once_flag.

  • There is no need for a non‐thread‐safe version of DelayedInit. std::optional will suffice in these cases.

Member Functions

Name

Description

DelayedInit [constructor]

Constructors

operator= [deleted]

Deleted copy assignment; DelayedInit is not copyable.

has_value

Checks whether the value has been initialized.

operator*

Returns the stored value without checking for initialization.

operator‐>

Accesses members of the stored value.

try_emplace

try_emplace overloads

try_emplace_with

Gets the pre‐existing value if already initialized or creates the value returned by the provided factory function. If the value already exists, then the provided function is not called.

value

Returns the stored value, throwing if it is not initialized.

operator bool

Checks whether the value has been initialized.

Created with MrDocs