Scroll to navigation

std::allocate_shared,std::allocate_shared_for_overwrite(3) C++ Standard Libary std::allocate_shared,std::allocate_shared_for_overwrite(3)

NAME

std::allocate_shared,std::allocate_shared_for_overwrite - std::allocate_shared,std::allocate_shared_for_overwrite

Synopsis


Defined in header <memory>
template< class T, class Alloc, class... Args > (since C++11)
shared_ptr<T> allocate_shared( const Alloc& alloc, Args&&... (1) (T is non-array)
args );
template< class T, class Alloc > (since C++20)
shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t (2) (T is U[])
N );
template< class T, class Alloc > (3) (since C++20)
shared_ptr<T> allocate_shared( const Alloc& alloc ); (T is U[N])
template< class T, class Alloc >


shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t (4) (since C++20)
N, (T is U[])


const std::remove_extent_t<T>& u );
template< class T, class Alloc >
(since C++20)
shared_ptr<T> allocate_shared( const Alloc& alloc, (5) (T is U[N])


const std::remove_extent_t<T>& u );
template< class T, class Alloc > (since C++20)
shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc (6) (T is not U[])
);
template< class T, class Alloc > (since C++20)
shared_ptr<T> allocate_shared_for_overwrite( const Alloc& (7) (T is U[])
alloc, std::size_t N );


1) Constructs an object of type T and wraps it in a std::shared_ptr using args as
the parameter list for the constructor of T. The object is constructed as if by the
expression
::new (pv) T(v)
(until C++20)
std::allocator_traits<A2>::construct(a, pv, v)
(since C++20), where pv is an internal void* pointer to storage suitable to hold an
object of type T and a is a copy of the allocator rebound to std::remove_cv_t<T>.
The storage is typically larger than sizeof(T) in order to use one allocation for
both the control block of the shared pointer and the T object. The std::shared_ptr
constructor called by this function enables shared_from_this with a pointer to the
newly constructed object of type T. All memory allocation is done using a copy of
alloc, which must satisfy the Allocator requirements. This overload participates in
overload resolution only if T is not an array type
2,3) Same as (1), but the object constructed is a possibly-multidimensional array
whose every non-array element is initialized as if by the expression
std::allocator_traits<A2>::construct(a2, pv) where a2 of type A2 is the copy of the
allocator rebound to manage objects of type
std::remove_cv_t<std::remove_all_extents_t<T>>. The overload (2) creates an array of
size N along its first dimension. The array elements are initialized in ascending
order of their addresses, and when their lifetime ends are destroyed in the reverse
order of their original construction.
4,5) Same as (2,3), but the elements of the array are initialized from the default
value u. If std::remove_extent_t<T> is not itself an array type, then this is
performed as if by the same allocator expression as in (1), except that the
allocator is rebound to the std::remove_cv_t<std::remove_all_extents_t<T>>.
Otherwise, this is performed as if by initializing every non-array element of the
(possibly multidimensional) array with the corresponding element from u using the
same allocator expression as in (1), except that the allocator is rebound to the
type std::remove_cv_t<std::remove_all_extents_t<T>>. The overload (4) creates an
array of size N along the first dimension. The array elements are initialized in
ascending order of their addresses, and when their lifetime ends are destroyed in
the reverse order of their original construction.
6) Same as (1) if T is not an array type and (3) if T is U[N], except that the
created object is default-initialized.
7) Same as (2), except that the individual array elements are default-initialized.


For allocate_shared, the object
(or the individual array elements for (2-5))
(since C++20) are destroyed via the expression std::allocator_traits<A2>::destroy(a,
p), where p is a pointer to the object and a is a copy of the allocator passed to
allocate_shared, rebound to the type of the object being destroyed.


For allocate_shared_for_overwrite, the object (or individual elements
if T is an array type) will be destroyed by p->~X(), where p is a (since C++20)
pointer to the object and X is its type.

Parameters


alloc - The Allocator to use.
args... - list of arguments with which an instance of T will be constructed.
N - array size to use
u - the initial value to initialize every element of the array

Return value


std::shared_ptr of an instance of type T.

Exceptions


Can throw the exceptions thrown from Alloc::allocate() or from the constructor of T.
If an exception is thrown, (1) has no effect.
If an exception is thrown during the construction of the array, already-initialized
elements are destroyed in reverse order
(since C++20)

Notes


Like std::make_shared, this function typically performs only one allocation, and
places both the T object and the control block in the allocated memory block (the
standard recommends but does not require this, all known implementations do this). A
copy of alloc is stored as part of the control block so that it can be used to
deallocate it once both shared and weak reference counts reach zero.


Unlike the std::shared_ptr constructors, std::allocate_shared does not accept a
separate custom deleter: the supplied allocator is used for destruction of the
control block and the T object, and for deallocation of their shared memory block.


std::shared_ptr supports array types (as of C++17), but
std::allocate_shared does not. This functionality is supported by (until C++20)
boost::allocate_shared.


A constructor enables shared_from_this with a pointer ptr of type U* means that it
determines if U has an
unambiguous and accessible
(since C++17) base class that is a specialization of std::enable_shared_from_this,
and if so, the constructor evaluates the statement:


if (ptr != nullptr && ptr->weak_this.expired())
ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(*this,
const_cast<std::remove_cv_t<U>*>(ptr));


Where weak_this is the hidden mutable std::weak_ptr member of
std::enable_shared_from_this. The assignment to the weak_this member is not atomic
and conflicts with any potentially concurrent access to the same object. This
ensures that future calls to shared_from_this() would share ownership with the
std::shared_ptr created by this raw pointer constructor.


The test ptr->weak_this.expired() in the exposition code above makes sure that
weak_this is not reassigned if it already indicates an owner. This test is required
as of C++17.


Feature-test macro: __cpp_lib_smart_ptr_for_overwrite (for overloads (6,7))

See also


constructor constructs new shared_ptr
(public member function)
make_shared creates a shared pointer that manages a new object
make_shared_for_overwrite (function template)
(C++20)

2022.07.31 http://cppreference.com