Pigweed
C/C++ API Reference
|
Public Types | |
using | value_type = T |
Public Member Functions | |
template<typename... Args, typename std::enable_if<!std::is_same< void(std::decay_t< Args > &...), void(NoDestructor &)>::value , int , ::type = 0> | |
constexpr | NoDestructor (Args &&... args) |
constexpr | NoDestructor (const T &x) |
constexpr | NoDestructor (T &&x) |
NoDestructor (const NoDestructor &)=delete | |
NoDestructor & | operator= (const NoDestructor &)=delete |
constexpr const T & | operator* () const |
constexpr T & | operator* () |
constexpr const T * | operator-> () const |
constexpr T * | operator-> () |
Helper type to create a global or function-local static variable of type T
when T
has a non-trivial destructor. Storing a T
in a pw::NoDestructor<T>
will prevent ~T()
from running, even when the variable goes out of scope. pw::NoDestructor<T>
provides an API similar to std::optional
. Use *
or ->
to access the wrapped type.
This class is useful when a variable has static storage duration but its type has a non-trivial destructor. Destructor ordering is not defined and can cause issues in multithreaded environments. Additionally, removing destructor calls can save code size.
Even though pw::NoDestructor
does not call the destructor, classes with a private destructor must friend class pw::NoDestructor<CrashInDestructor>
to be used with pw::NoDestructor
.
Except in generic code, do not use pw::NoDestructor<T>
with trivially destructible types. Use the type directly instead. If the variable can be constexpr
, make it constexpr
.
NoDestructor
instances can be constinit
if T
has a constexpr
constructor. In C++20, NoDestructor
instances may be constexpr
if T
has a constexpr
destructor. NoDestructor
is unnecessary for literal types.
NoDestructor<T>
instances may be constant initialized, whether they are constinit
or not. This may be undesirable for large objects, since moving them from .bss
to .data
increases binary size. To prevent this, use pw::RuntimeInitGlobal
, which prevents constant initialization and removes the destructor.Example usage:
In Clang, pw::NoDestructor
can be replaced with the [[clang::no_destroy]] attribute. pw::NoDestructor<T>
is similar to Chromium’s base::NoDestructor<T>
in src/base/no_destructor.h.
NoDestructor
can cause memory leaks and other problems. Only skip destructors when you know it is safe to do so.