|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Modifiers | ||||
| Observers | ||||
(C++17) | ||||
(until C++20*) | ||||
(C++26) | ||||
(C++26) | ||||
| Non-member functions | ||||
allocate_sharedallocate_shared_for_overwrite (C++20) | ||||
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20) | ||||
functions(until C++26*) | ||||
| Helper classes | ||||
(C++20) | ||||
| Deduction guides(C++17) |
Defined in header <memory> | ||
template<class T,class Alloc,class...Args> shared_ptr<T> allocate_shared(const Alloc& alloc, Args&&...args); | (1) | (since C++11) |
template<class T,class Alloc> shared_ptr<T> allocate_shared(const Alloc& alloc,std::size_t N); | (2) | (since C++20) |
template<class T,class Alloc> shared_ptr<T> allocate_shared(const Alloc& alloc); | (3) | (since C++20) |
template<class T,class Alloc> shared_ptr<T> allocate_shared(const Alloc& alloc,std::size_t N, | (4) | (since C++20) |
template<class T,class Alloc> shared_ptr<T> allocate_shared(const Alloc& alloc, | (5) | (since C++20) |
template<class T,class Alloc> shared_ptr<T> allocate_shared_for_overwrite(const Alloc& alloc); | (6) | (since C++20) |
template<class T,class Alloc> shared_ptr<T> allocate_shared_for_overwrite(const Alloc& alloc, | (7) | (since C++20) |
Allocates memory for an object using a copy ofalloc (rebound for an unspecifiedvalue_type) and initialize the object with the supplied arguments. Returns astd::shared_ptr object managing the newly created object.
T, and is constructed as if bystd::allocator_traits<Alloc>::constructAlloc, and it is a potentially rebound copy ofalloc.This overload participates in overload resolution only if | (since C++20) |
T is an unbounded array type.T. Each element has a default initial value.T is a bounded array type.T is an unbounded array type.T. Each element has the initial valueu.T is a bounded array type.T.T is not an array type, the object is constructed as if by::new(pv) T, wherepv is avoid* pointer to storage suitable to hold an object of typeT. If the object is to be destroyed, it is destroyed as if bypt->~T(), wherept is a pointer to that object of typeT.T is a bounded array type, the initial value is unspecified for each element.T is not an array type or is an bounded array type.T is an unbounded array type.
Initializing and destroying array elementsIn the description below,a is of type Array elements of type
2,3)std::allocator_traits<Alloc>::construct(a, pu) 4,5)std::allocator_traits<Alloc>::construct(a, pu, u) 6,7)::new(pv) U
When the lifetime of the object managed by the returnstd::shared_ptr ends, or when the initialization of an array element throws an exception, the initialized elements are destroyed in the reverse order of their original construction. For each array element of non-array type 2-5)std::allocator_traits<Alloc>::destroy(a, pu), wherepu is aU* pointer to that array element of type U6,7)pu->~U(), wherepu is a pointer to that array element of type U | (since C++20) |
| alloc | - | theAllocator to use |
| args... | - | list of arguments with which an instance ofT will be constructed |
| N | - | array size to use |
| u | - | the initial value to initialize every element of the array |
std::shared_ptr to an object of typeT orstd::remove_extent_t<T>[N] ifT is an unbounded array type(since C++20).
For the returnedstd::shared_ptrr,r.get() returns a non-null pointer andr.use_count() returns1.
Can throw the exceptions thrown fromAlloc::allocate() or from the constructor ofT. 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).
These functions will typically allocate more memory thansizeof(T) to allow for internal bookkeeping structures such as reference counts.
Likestd::make_shared, this function typically performs only one allocation, and places both theT 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 ofalloc 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 thestd::shared_ptrconstructors,std::allocate_shared does not accept a separate custom deleter: the supplied allocator is used for destruction of the control block and theT object, and for deallocation of their shared memory block.
std::shared_ptr supports array types (as of C++17), but | (until C++20) |
A constructorenablesshared_from_this with a pointerptr of typeU* means that it determines ifU has anunambiguous and accessible(since C++17) base class that is a specialization ofstd::enable_shared_from_this, and if so, the constructor evaluatesif(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));.
The assignment to theweak_this is not atomic and conflicts with any potentially concurrent access to the same object. This ensures that future calls toshared_from_this() would share ownership with thestd::shared_ptr created by this raw pointer constructor.
The testptr->weak_this .expired() in the code above makes sure thatweak_this is not reassigned if it already indicates an owner. This test is required as of C++17.
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_smart_ptr_for_overwrite | 202002L | (C++20) | Smart pointer creation with default initialization (std::allocate_shared_for_overwrite,std::make_shared_for_overwrite,std::make_unique_for_overwrite); overloads(6,7) |
#include <cstddef>#include <iostream>#include <memory>#include <memory_resource>#include <vector> class Value{int i;public: Value(int i): i(i){std::cout<<"Value(), i = "<< i<<'\n';} ~Value(){std::cout<<"~Value(), i = "<< i<<'\n';}void print()const{std::cout<<"i = "<< i<<'\n';}}; int main(){// Create a polymorphic allocator using the monotonic buffer resourcestd::byte buffer[sizeof(Value)*8];std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer));std::pmr::polymorphic_allocator<Value> allocator(&resource); std::vector<std::shared_ptr<Value>> v; for(int i{}; i!=4;++i)// Use std::allocate_shared with the custom allocator v.emplace_back(std::allocate_shared<Value>(allocator, i)); for(constauto& sp: v) sp->print();}//< All shared pointers will automatically clean up when they go out of scope.
Output:
Value(), i = 0Value(), i = 1Value(), i = 2Value(), i = 3i = 0i = 1i = 2i = 3~Value(), i = 0~Value(), i = 1~Value(), i = 2~Value(), i = 3
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3216 | C++20 | std::allocate_shared always rebound theallocator before constructing and destroying objects | rebind is optional |
| LWG 4024 | C++20 | it was unclear how the objects constructed instd::allocate_shared_for_overwrite are destroyed | made clear |
constructs newshared_ptr(public member function)[edit] | |
| creates a shared pointer that manages a new object (function template)[edit] |