A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://en.cppreference.com/w/cpp/language/../named_req/../memory/shared_ptr/allocate_shared.html below:

std::allocate_shared, std::allocate_shared_for_overwrite - cppreference.com

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) (4) (since C++20) template< class T, class Alloc >

shared_ptr<T> allocate_shared( const Alloc& alloc,

                               const std::remove_extent_t<T>& u );
(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,

                                             std::size_t N );
(7) (since C++20)

Allocates memory for an object using a copy of alloc (rebound for an unspecified value_type) and initialize the object with the supplied arguments. Returns a std::shared_ptr object managing the newly created object.

In the description above,

a

is of type

Alloc

, and it is a potentially rebound copy of

alloc

.

This overload participates in overload resolution only if T is not an array type.

(since C++20)

This overload participates in overload resolution only if T is an unbounded array type.

3) The object is of type T. Each element has a default initial value.

This overload participates in overload resolution only if T is a bounded array type.

This overload participates in overload resolution only if T is an unbounded array type.

5) The object is of type T. Each element has the initial value u.

This overload participates in overload resolution only if T is a bounded array type.

6)

The object is of type

T

.

This overload participates in overload resolution only if T is not an array type or is an bounded array type.

7)

The object is of type

std::remove_extent_t<T>[N]

. The initial value is unspecified for each element.

This overload participates in overload resolution only if T is an unbounded array type.

Initializing and destroying array elements

In the description below, a is of type Alloc, and it is a potentially rebound copy of alloc.

Array elements of type U are initialized in ascending order of their addresses.

6,7) ::new (pv) U

When the lifetime of the object managed by the return std::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 U to be destroyed, it is destroyed as if by the following expression:

2-5) std::allocator_traits<Alloc>::destroy(a, pu)

, where

pu

is a

U*

pointer to that array element of type

U

6,7) pu->~U(), where pu is a pointer to that array element of type U

(since C++20) [edit] 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 [edit] Return value

std::shared_ptr to an object of type T or std::remove_extent_t<T>[N] if T is an unbounded array type(since C++20).

For the returned std::shared_ptr r, r.get() returns a non-null pointer and r.use_count() returns 1.

[edit] 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).

[edit] Notes

These functions will typically allocate more memory than sizeof(T) to allow for internal bookkeeping structures such as reference counts.

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.

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 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));
.

The assignment to the weak_this 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 code above makes sure that weak_this is not reassigned if it already indicates an owner. This test is required as of C++17.

[edit] Example
#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 resource
    std::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 (const auto& sp : v)
        sp->print();
} //< All shared pointers will automatically clean up when they go out of scope.

Output:

Value(), i = 0
Value(), i = 1
Value(), i = 2
Value(), i = 3
i = 0
i = 1
i = 2
i = 3
~Value(), i = 0
~Value(), i = 1
~Value(), i = 2
~Value(), i = 3
[edit] Defect reports

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 the
allocator before constructing and destroying objects rebind is optional LWG 4024 C++20 it was unclear how the objects constructed in
std::allocate_shared_for_overwrite are destroyed made clear [edit] See also

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4