absl::NoDestructor

NoDestructor<T> is a wrapper around an object of type T that behaves as an object of type T but never calls T's destructor. NoDestructor<T> makes it safer and/or more efficient to use such objects in static storage contexts, ideally as function scope static variables.

Synopsis

Declared in <absl/base/no_destructor.h>

template<typename T>
class NoDestructor;

Description

An instance of absl::NoDestructor<T> has similar type semantics to an instance of T:

* Constructs in the same manner as an object of type T through perfect forwarding. * Provides pointer/reference semantic access to the object of type T via ->, *, and get(). (Note that const NoDestructor<T> works like a pointer to const T.)

Additionally, NoDestructor<T> provides the following benefits:

* Never calls T's destructor for the object * If the object is a function-local static variable, the type can be lazily constructed.

An object of type NoDestructor<T> is "trivially destructible" in the notion that its destructor is never run.

Usage as Function Scope Static Variables

Function static objects will be lazily initialized within static storage:

// Function scope. const std::string& MyString() { static const absl::NoDestructor<std::string> x("foo"); return *x; }

For function static variables, NoDestructor avoids heap allocation and can be inlined in static storage, resulting in exactly-once, thread-safe construction of an object, and very fast access thereafter (the cost is a few extra cycles).

Using NoDestructor<T> in this manner is generally better than other patterns which require pointer chasing:

// Prefer using absl::NoDestructor<T> instead for the static variable. const std::string& MyString() { static const std::string* x = new std::string("foo"); return *x; }

Usage as Global Static Variables

NoDestructor<T> allows declaration of a global object of type T that has a non-trivial destructor since its destructor is never run. However, such objects still need to worry about initialization order, so such use is not recommended, strongly discouraged by the Google C++ Style Guide, and outright banned in Chromium. See https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables

// Global or namespace scope. absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};

Note that if your object already has a trivial destructor, you don't need to use NoDestructor<T>.

Member Functions

NameDescription
NoDestructor [constructor]Constructors
operator= [deleted]Deleted: NoDestructor is not copy-assignable.
get get overloads
operator* Dereference operators
operator-> Member access operators

Deduction Guides

NameDescription
NoDestructor<T> Provide 'Class Template Argument Deduction': the type of NoDestructor's T will be the same type as the argument passed to NoDestructor's constructor.