Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The allocator is intended to be used to allocate and deallocate <em>internal <code>shared_ptr</code> details</em>, not the object.</p> <p>That is, while the deleter gives us full control over our shared object (because we control how it's acquired and released), the allocator parameter gives us control over the internal details of our object's shared nature.</p> <p>If you look at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm" rel="nofollow noreferrer">N2351</a>, at the end of the allocator proposal they note that Boost has implemented the feature, and link to an example that was made to demonstrate its use. </p> <p>Here is that example, verbatim:</p> <pre><code>#include &lt;boost/config.hpp&gt; // shared_ptr_alloc2_test.cpp // // Copyright (c) 2005 Peter Dimov // // 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) #include &lt;boost/detail/lightweight_test.hpp&gt; #include &lt;boost/shared_ptr.hpp&gt; #include &lt;memory&gt; #include &lt;cstddef&gt; // test_allocator struct test_allocator_base { int id_; static int last_global_id_; static int count_; explicit test_allocator_base( int id ): id_( id ) { } }; int test_allocator_base::last_global_id_ = 0; int test_allocator_base::count_ = 0; template&lt;class T&gt; class test_allocator: public test_allocator_base { public: typedef T * pointer; typedef T const * const_pointer; typedef T &amp; reference; typedef T const &amp; const_reference; typedef T value_type; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; private: static T * last_pointer_; static std::size_t last_n_; static int last_id_; public: template&lt;class U&gt; struct rebind { typedef test_allocator&lt;U&gt; other; }; pointer address( reference r ) const { return &amp;r; } const_pointer address( const_reference s ) const { return &amp;s; } explicit test_allocator( int id = 0 ): test_allocator_base( id ) { } template&lt;class U&gt; test_allocator( test_allocator&lt;U&gt; const &amp; r ): test_allocator_base( r ) { } template&lt;class U&gt; test_allocator &amp; operator=( test_allocator&lt;U&gt; const &amp; r ) { test_allocator_base::operator=( r ); return *this; } void deallocate( pointer p, size_type n ) { BOOST_TEST( p == last_pointer_ ); BOOST_TEST( n == last_n_ ); BOOST_TEST( id_ == last_id_ ); --count_; ::operator delete( p ); } pointer allocate( size_type n, void const * ) { T * p = static_cast&lt; T* &gt;( ::operator new( n * sizeof( T ) ) ); last_pointer_ = p; last_n_ = n; last_id_ = id_; last_global_id_ = id_; ++count_; return p; } void construct( pointer p, T const &amp; t ) { new( p ) T( t ); } void destroy( pointer p ) { p-&gt;~T(); } size_type max_size() const { return size_type( -1 ) / sizeof( T ); } }; template&lt;class T&gt; T * test_allocator&lt;T&gt;::last_pointer_ = 0; template&lt;class T&gt; std::size_t test_allocator&lt;T&gt;::last_n_ = 0; template&lt;class T&gt; int test_allocator&lt;T&gt;::last_id_ = 0; template&lt;class T, class U&gt; inline bool operator==( test_allocator&lt;T&gt; const &amp; a1, test_allocator&lt;U&gt; const &amp; a2 ) { return a1.id_ == a2.id_; } template&lt;class T, class U&gt; inline bool operator!=( test_allocator&lt;T&gt; const &amp; a1, test_allocator&lt;U&gt; const &amp; a2 ) { return a1.id_ != a2.id_; } template&lt;&gt; class test_allocator&lt;void&gt;: public test_allocator_base { public: typedef void * pointer; typedef void const * const_pointer; typedef void value_type; template&lt;class U&gt; struct rebind { typedef test_allocator&lt;U&gt; other; }; explicit test_allocator( int id = 0 ): test_allocator_base( id ) { } template&lt;class U&gt; test_allocator( test_allocator&lt;U&gt; const &amp; r ): test_allocator_base( r ) { } template&lt;class U&gt; test_allocator &amp; operator=( test_allocator&lt;U&gt; const &amp; r ) { test_allocator_base::operator=( r ); return *this; } }; // struct X { static int instances; X() { ++instances; } ~X() { --instances; } private: X( X const &amp; ); X &amp; operator=( X const &amp; ); }; int X::instances = 0; int main() { BOOST_TEST( X::instances == 0 ); boost::shared_ptr&lt;void&gt; pv( new X, boost::checked_deleter&lt;X&gt;(), std::allocator&lt;X&gt;() ); BOOST_TEST( X::instances == 1 ); pv.reset( new X, boost::checked_deleter&lt;X&gt;(), test_allocator&lt;float&gt;( 42 ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( test_allocator_base::last_global_id_ == 42 ); BOOST_TEST( test_allocator_base::count_ &gt; 0 ); pv.reset(); BOOST_TEST( X::instances == 0 ); BOOST_TEST( test_allocator_base::count_ == 0 ); pv.reset( new X, boost::checked_deleter&lt;X&gt;(), test_allocator&lt;void&gt;( 43 ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( test_allocator_base::last_global_id_ == 43 ); pv.reset( new X, boost::checked_deleter&lt;X&gt;(), std::allocator&lt;void&gt;() ); BOOST_TEST( X::instances == 1 ); pv.reset(); BOOST_TEST( X::instances == 0 ); return boost::report_errors(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload