$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Phil Bouchard (philippe_at_[hidden])
Date: 2008-08-29 23:21:28
"Scott McMurray" <me22.ca+boost_at_[hidden]> wrote in message 
news:fa28b9250808290914l19a6cf1fue658229148ec0f09_at_mail.gmail.com...
[...]
> It's not an allocator, and it's often useful in strange ways:
>
>    shared_ptr<FILE> f( fopen("file.txt"), fclose );
>
> The fact that the deleter is specified on initialization is also
> essential in that it allows you to create shared_ptrs to incomplete
> types:
>
>    struct S { auto_ptr<S> p; }; // illegal
>    struct S { shared_ptr<S> p; }; // fine
>
> So I don't really see your point, here.
I think you're confusing the allocator and the deleter but I am exclusively 
referring to the allocator.  I just looked at the code of shared_ptr today 
and it is very similar to what I wrote yesterday:
template<class P, class D, class A>
    class sp_counted_impl_pda: public sp_counted_base
    {
        ...
        virtual void destroy() // nothrow
        {
            typedef typename A::template rebind< this_type >::other A2;
            A2 a2( a_ );
            this->~this_type();
            a2.deallocate( this, 1 );
            // ugh!
        }
    };
This is ill-formed code.  It's obvious shared_ptr is still in its 
theoretical stage as far as the allocator is concerned; because 
std::allocator is a bad example to start with.  Let's take a real one like 
the following:
// allocator
template <typename T>
    class my_allocator
    {
        boost::fast_pool_allocator pool_;
        ...
        void deallocate(pointer & p)
        {
            pool_.deallocate(p.release());
            // do not touch "this" anymore starting here!!
        }
    };
The way shared_ptr works right now, the pool is going to be copied entirely 
on to the sp_counted_impl_pda object.  The problem here is that the pool is 
going to delete its own instance when deallocate() is called.  The allocator 
variable sp_counted_impl_pda::a_ will need to be changed for a functor or a 
global function pointer before anything else.
Moreover using and allocator explicitly using release() saves some 
unnecessary overhead for tested classes and library programmers.  One might 
wonder why using a smart pointer for well tested classes?  Well it turns out 
shifted_ptr is much more efficient this way because all node allocations 
will be part of the same set.
-Phil