Suppose I have a type template parameter T.
And suppose I have a
std::aligned_storage
typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;
storage
storage
new (& ???) T(a,b,c);
new (&storage) T(a,b,c);
new (static_cast<void*>(&storage)) T(a,b,c);
new (reinterpret_cast<T*>(&storage)) T(a,b,c);
new (static_cast<T*>(static_cast<void*>(&storage));
The most paranoid way is
::new ((void *)::std::addressof(storage)) T(a, b, c);
Explanation:
::std::addressof
guards against overloaded unary operator&
on storage
, which is technically allowed by the standard. (Though no sane implementation would do it.) The ::std
guards against any non-top-level namespaces (or classes) called std
that might be in scope.(void *)
(which in this case is a static_cast
) ensures that you call the placement operator new
taking a void *
rather than something else like decltype(storage) *
.::new
skips any class-specific placement operator new
s, ensuring that the call goes to the global one.Together, this guarantees that the call goes to the library placement operator new
taking a void *
, and that the T
is constructed at where storage
is.
In most sane programs, though,
new (&storage) T(a,b,c);
should be sufficient.