Introduction
Synopsis
Free Functions
Example
History
Originally the Boost function templates make_shared
and
allocate_shared
were for efficient allocation of single
objects only. There was a need to have efficient, single, allocation of
arrays. One criticism of shared_array was
always the lack of a make_shared utility
which ensures only a single allocation for an array.
The header files <boost/smart_ptr/make_shared_array.hpp> and
<boost/smart_ptr/allocate_shared_array.hpp> provide new function
templates, make_shared
and allocate_shared
,
to address this need. make_shared
uses the global
operator new
to allocate memory, whereas
allocate_shared
uses an user-supplied allocator,
allowing finer control.
namespace boost { template<typename U> // U = T[] shared_ptr<U> make_shared(size_t size); template<typename U, typename A> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, size_t size); #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template<typename U, typename... Args> // U = T[] shared_ptr<U> make_shared(size_t size, Args&&... args); template<typename U, typename... Args> // U = T[N] shared_ptr<U> make_shared(Args&&... args); template<typename U, typename A, typename... Args> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args); template<typename U, typename A, typename... Args> // U = T[N] shared_ptr<U> allocate_shared(const A& allocator, Args&&... args); #endif #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template<typename U, typename... Args> // U = T[N] shared_ptr<U> make_shared(const T (&list)[N]); template<typename U, typename... Args> // U = T[][N] shared_ptr<U> make_shared(size_t size, const T (&list)[N]); template<typename U, typename... Args> // U = T[M][N] shared_ptr<U> make_shared(const T (&list)[N]); template<typename U, typename A, typename... Args> // U = T[N] shared_ptr<T[> allocate_shared(const A& allocator, const T (&list)[N]); template<typename U, typename A, typename... Args> // U = T[][N] shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]); template<typename U, typename A, typename... Args> // U = T[M][N] shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]); #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) template<typename U, typename... Args> // U = T[] shared_ptr<U> make_shared(initializer_list<T> list); template<typename U, typename A, typename... Args> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list); #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template<typename U> // U = T[] shared_ptr<U> make_shared(size_t size, T&& value); template<typename U> // U = T[N] shared_ptr<U> make_shared(T&& value); template<typename U, typename A> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value); template<typename U, typename A> // U = T[N] shared_ptr<U> allocate_shared(const A& allocator, T&& value); #endif #endif template<typename U> // U = T[] shared_ptr<U> make_shared_noinit(size_t size); template<typename U> // U = T[N] shared_ptr<U> make_shared_noinit(); template<typename U, typename A> // U = T[] shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size); template<typename U, typename A> // U = T[N] shared_ptr<U> allocate_shared_noinit(const A& allocator); }
template<typename U, typename... Args> // U = T[] shared_ptr<U> make_shared(size_t size, Args&&... args); template<typename U, typename A, typename... Args> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args);
Requires: The expression
new(pointer) T(forward<Args>(args)...)
, wherepointer
is avoid*
pointing to storage suitable to hold an object of typeT
, shall be well-formed.A
shall be an Allocator, as described in section 20.1.5 (Allocator requirements) of the C++ Standard. The copy constructor and destructor ofA
shall not throw.Effects: Allocates memory suitable for an array of type
T
and sizesize
and constructs an array of objects in it via the placement new expressionnew(pointer) T()
ornew(pointer) T(args...)
.allocate_shared
uses a copy ofallocator
to allocate memory. If an exception is thrown, has no effect.Returns: A
shared_ptr
instance that stores and owns the address of the newly constructed array of typeT
and sizesize
.Postconditions:
get() != 0 && use_count() == 1
.Throws:
bad_alloc
, or an exception thrown fromA::allocate
or the constructor ofT
.Notes: This implementation allocates the memory required for the returned
shared_ptr
and an array of typeT
of sizesize
in a single allocation. This provides efficiency to equivalent to an intrusive smart array pointer.The prototypes shown above are used if your compiler supports r-value references and variadic templates. They perfectly forward the
args
parameters to the constructors ofT
for each array element.Otherwise, you can use the overloads which take only the array size (and the allocator in case of
allocate_shared
) and do not take any constructor arguments. These overloads invoke the default constructor ofT
for each array element.
template<typename U, typename... Args> // U = T[N] shared_ptr<U> make_shared(Args&&... args); template<typename U, typename A, typename... Args> // U = T[N] shared_ptr<U> allocate_shared(const A& allocator, Args&&... args);
Description: These overloads of the utilities above are for a fixed size array.
template<typename U, typename... Args> // U = T[] shared_ptr<U> make_shared(initializer_list<T> list); template<typename U, typename A, typename... Args> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list);
Description: These overloads initialize the array elements from the initializer list.
template<typename U, typename... Args> // U = T[N] shared_ptr<U> make_shared(const T (&list)[N]); template<typename U, typename A, typename... Args> // U = T[N] shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);
Description: These overloads of the utilities above are for a fixed size array.
template<typename U, typename... Args> // U = T[][N] shared_ptr<U> make_shared(size_t size, const T (&list)[N]); template<typename U, typename A, typename... Args> // U = T[][N] shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);
Description: These overloads initialize inner array elements from the initializer list.
template<typename U, typename... Args> // U = T[M][N] shared_ptr<U> make_shared(const T (&list)[N]); template<typename U, typename A, typename... Args> // U = T[M][N] shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);
Description: These overloads of the utilities above are for a fixed size array.
template<typename U> // U = T[] shared_ptr<U> make_shared(size_t size, T&& value); template<typename U, typename A> // U = T[] shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value);
Description: These overloads initialize array elements with the given value.
template<typename U> // U = T[N] shared_ptr<U> make_shared(T&& value); template<typename U, typename A> // U = T[N] shared_ptr<U> allocate_shared(const A& allocator, T&& value);
Description: These overloads of the utilities above are for a fixed size array.
template<typename U> // U = T[] shared_ptr<U> make_shared_noinit(size_t size); template<typename U, typename A> // U = T[] shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
Description: These overloads do not perform any value initialization of elements.
template<typename U> // U = T[N] shared_ptr<U> make_shared_noinit(); template<typename U, typename A> // U = T[N] shared_ptr<U> allocate_shared_noinit(const A& allocator);
Description: These overloads of the utilities above are for a fixed size array.
An example of each overload of make_shared for arrays:
boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size); boost::shared_ptr<point[]> a2 = boost::make_shared<point[]>(size, x, y); boost::shared_ptr<point[5]> a3 = boost::make_shared<point[5]>(x, y); boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3}); boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3}); boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3}); boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3}); boost::shared_ptr<point[]> a8 = boost::make_shared<point[]>(size, {x, y}); boost::shared_ptr<point[5]> a9 = boost::make_shared<point[5]>({x, y}); boost::shared_ptr<int[]> a10 = boost::make_shared_noinit<int[]>(size); boost::shared_ptr<int[5]> a11 = boost::make_shared_noinit<int[5]>();
November 2012. Glen Fernandes contributed implementations of make_shared and allocate_shared for arrays.
$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $
Copyright 2012 Glen Fernandes. Distributed under the Boost Software License, Version 1.0. See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.