Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-09-02 10:22:25

Gregory Colvin <gregory.colvin_at_[hidden]> writes:

>> I think part of my point was that *nobody* needs what they offer, if
>> you include construct/destroy.
> Or rather that some implementations have failed to use what they
> offer, and our standard unfortunately doesn't insist that they do.

It's not unfortunate if it adds nothing, which is what I believe.

> Another reason construct is needed is that Allocator::pointer might
> be a proxy, with operator* and operator-> but not necessarily a
> conversion to void* or even T*.

Doesn't matter; you can always get the address of an object. See

>> In fact, construct requires undefined behavior for non-POD T
>> because you can't copy its T* argument which points into raw
>> storage.
> I don't understand what you mean by this. Are you claiming that
> it is undefined to copy just a pointer to raw storage?

Unless the pointer has the right type, yes.

> If so, then how is placement new not undefined?

It uses a void*, as shown in your code snippet below.

> The standard says:
> a.construct(p,t)
> Effect: new((void*)p) T(t)
>> I think I would rather see a MPL lambda expression or metafunction
>> class interface for allocator type parameters. It makes little sense
>> for the allocator's user to be choosing its value_type.
>> Something like:
>> some_allocator<_1>
>> or
>> struct select_allocator
>> {
>> template <class T>
>> struct apply
>> {
>> typedef some_allocator<T> type;
>> };
>> };
>> with some_allocator's interface being like what's required for
>> std::allocator but not including misplaced interface bits such as
>> address/construct/destroy, and possibly max_size -- these can be added
>> by a std::allocator facade wrapper if neccessary.
>> I'm not sure we need a simple version and a complicated version.
> I'm not clear how you intend the above to be used, or what you
> intend it to be a replacement for.

I intend it to be the sort of type parameter that gets passed to our
objects which need custom allocation in place of a standard allocator.
It's ridiculous, IMO, to pass allocator<T> to a node-based container
which is *never* going to allocate a T object. The container itself
should decide which type the allocator template gets instantiated on,

    mpl::apply<mpl::lambda<S>, Node>::type

       this is approximately the same as:

         S::template apply<U>::type == some_allocator<U>

       except that it works when S is the lambda expression
       some_allocator<_1> as well as when it's the select_allocator
       metafunction class below it.

What the rebind requirement in the allocator means for pool
allocation, for example, is that a pool_allocator<T> object must
either be stateless (in which case allocator inequality is
meaningless) or effectively be able to allocate blocks of *any* size
and alignment, rather than just as appropriate for T. It's a
conceptual mess.

Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at