Subject: Re: [boost] [ptr_container] ptr_vector across DLL boundaries
From: Thorsten Ottosen (thorsten.ottosen_at_[hidden])
Date: 2009-06-26 04:45:27
Christian Schladetsch skrev:
> On Fri, Jun 26, 2009 at 9:26 AM, Thorsten Ottosen <
> thorsten.ottosen_at_[hidden]> wrote:
>> Christian Schladetsch skrev:
>>> How does a clone_allocator make a new clone, if it needs access to the
>>> allocator in the parent ptr_container? [snip]
>>> What am I missing?
>> Nothing, I think. This seems like something it was not designed for,
>> on the cnotrary the clone is currently always allocated by someone else.
> Then what is the point of clone_allocator?
It does provide some room for customization. But it was deliberately
kept very conservative, so we can extend it when we need to in light of
>> The current design uses static functions, and so there can be no stateful
>> I thought a little about this, but have not come up with a solution.
>> For example, how do we design an allocator that knows how to clone a
>> class hierarchy? Only the class itself knows how to clone itself because it
>> knows the exact type. OTOH, the classes in the class hieararchy doesn't know
>> about the allocator.
>> We might try a new way to clone objects by replacing
>> virtual Base::clone() const = 0;
> Isn't this what a copy constructor is for?
Types in object hierarchies usually don't expose their copy-constructor
to avoid sliving. Furthermore, and more importantly, you loose the
concrete type of the objects by having a container of pointers to the
base class. Virtual functions are the most elegant way to ask the object
for a copy of the right type.
> I've had a quick look at <boost/ptr_container/ptr_inserter.hpp> and related
> files, and it seems that whenever it currently says something like
> obj =
> it could say instead
> obj =
I guess it could.
> And then in a custom clone_allocator, you could say:
> struct my_clone_allocator
> template< class U, class Allocator >
> static U* allocate_clone( const U& r, Allocator &alloc)
> typename Allocator::template rebind<U>::other
> U *clone = my_alloc.allocate(1);
> my_alloc.construct(clone, r);
> return clone;
This requires a public copy-constructor which we must not impose as a
requirement, and even so it would not work because the concrete type is
lost. (let's ignore that it is not exception-safe).
But this raises another question I have: would we want all the objects
to be allocated from the same allocator type using rebind<>, or would we
like to use two different allocators.
> Or, pass in a rebound allocator to allocate_clone; it doesn't really matter.
> Point being, can you just pass the container's allocator to the
I can, but I feel it is unanswered whether it should be the underlying
container's allocator or simply the clone_allocator that somehow makes
it's own allocations.
And, as stated above, we also need to make sure that implementers of
clone() get the allocator. I'm not a fan of having users call rebind<>
inside each of their virtual clone() functions. It sounds very inelegant
That is why I suggested a non-templated allocator,
boost::clone_allocator, that can be used by all classes in the hierarchy.
> Another alternative is to make clone_allocator a concept and pass the
> either-or-both U and Allocator types to it at compile time, but I think it
> works just as well and more generally as a static method.
We have to allow non-static functions to support Robert's use case.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk