make_shared and allocate_shared

# make_shared and allocate_shared function templates

Introduction
Synopsis
Free Functions
Example

## Introduction

Consistent use of `shared_ptr` can eliminate the need to use an explicit `delete`, but alone it provides no support in avoiding explicit `new`. There have been repeated requests from users for a factory function that creates an object of a given type and returns a `shared_ptr` to it. Besides convenience and style, such a function is also exception safe and considerably faster because it can use a single allocation for both the object and its corresponding control block, eliminating a significant portion of `shared_ptr`'s construction overhead. This eliminates one of the major efficiency complaints about `shared_ptr`.

The header file <boost/make_shared.hpp> provides a family of overloaded 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.

The rationale for choosing the name `make_shared` is that the expression `make_shared<Widget>()` can be read aloud and conveys the intended meaning.

## Synopsis

    namespace boost {

      template<typename T> class shared_ptr;

      template<typename T>
        shared_ptr<T> make_shared();

      template<typename T, typename A>
        shared_ptr<T> allocate_shared( A const & );

    #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )	// C++0x prototypes

      template<typename T, typename... Args>
        shared_ptr<T> make_shared( Args && ... args );

      template<typename T, typename A, typename... Args>
        shared_ptr<T> allocate_shared( A const & a, Args && ... args );

    #else // no C++0X support

      template<typename T, typename Arg1 >
        shared_ptr<T> make_shared( Arg1 const & arg1 );
      template<typename T, typename Arg1, typename Arg2 >
        shared_ptr<T> make_shared( Arg1 const & arg1, Arg2 const & arg2 );
    // ...
      template<typename T, typename Arg1, typename Arg2, ..., typename ArgN >
        shared_ptr<T> make_shared( Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );

      template<typename T, typename A, typename Arg1 >
        shared_ptr<T> allocate_shared( A const & a, Arg1 const & arg1 );
      template<typename T, typename A, typename Arg1, typename Arg2 >
        shared_ptr<T> allocate_shared( Arg1 const & arg1, Arg2 const & arg2 );
    // ...
      template<typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN >
        shared_ptr<T> allocate_shared( A const & a, Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );

    #endif
    }

## Free Functions

    template<class T, class... Args>
        shared_ptr<T> make_shared( Args && ... args );
    template<class T, class A, class... Args>
        shared_ptr<T> allocate_shared( A const & a, Args && ... args );

> Requires: The expression `new( pv ) T( std::forward<Args>(args)... )`, where `pv` is a `void*` pointing to storage suitable to hold an object of type `T`, 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 of `A` shall not throw.

> Effects: Allocates memory suitable for an object of type `T` and constructs an object in it via the placement new expression `new( pv ) T()` or `new( pv ) T( std::forward<Args>(args)... )`. `allocate_shared` uses a copy of `a` 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 object of type `T`.

> Postconditions: `get() != 0 && use_count() == 1`.

> Throws: `bad_alloc`, or an exception thrown from `A::allocate` or the constructor of `T`.

> Notes: This implementation allocates the memory required for the returned `shared_ptr` and an object of type `T` in a single allocation. This provides efficiency equivalent to an intrusive smart pointer.

> The prototypes shown above are used if your compiler supports rvalue references and variadic templates. They perfectly forward the `args` parameters to the constructors of `T`.

> Otherwise, the implementation will fall back on forwarding the arguments to the constructors of `T` as const references. If you need to pass a non-const reference to a constructor of `T`, you may do so by wrapping the parameter in a call to `boost::ref`. In addition, you will be limited to a maximum of 9 arguments (not counting the allocator argument of allocate_shared).

## Example

    boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
    std::cout << *x;

$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $

Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess. 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.