From: Gregory Colvin (gregory.colvin_at_[hidden])
Date: 2003-08-31 14:55:32


On Sunday, Aug 31, 2003, at 13:13 America/Denver, David Abrahams wrote:
> Gregory Colvin <gregory.colvin_at_[hidden]> writes:
>
>>>> But indeed allocate/construct/deallocate/destroy is more work than
>>> ^^^^^^^^^ ^^^^^^^
>>> Oyeah. These two absolutely don't belong in allocator, period. Do
>>> any implementations even use them? Allocators exist to provide a
>>> point of customization for users, but you cannot/should not customize
>>> these.
>>
>> Conforming containers had better use them.
>
> I'm sorry, but I think that's flat wrong. What do you suppose that
> entry in column 2 of the allocator requirements table (20.1.5) means,
> after all?

It means any value returned by construct, destroy, or deallocate goes
unused.

>> And once you are down in the coal mine customizing what a pointer
>> is, I'm not sure you won't need to customize how to construct and
>> destroy.
>
> The class getting constructed/destroyed has full control over that or
> the language is utterly bustificated.

Yes, but the allocator may want to do something else as well, and
construct and destroy serve as hooks for whatever that may be.

>>> Using allocator is even more work than allocating raw memory with
>>> malloc and doing placement new and explicit destruction, then freeing
>>> the raw memory. That's my biggest complaint.
>>
>> It's new/delete
>>
>> T* p = new T();
>> ...
>> delete p;
>>
>> versus malloc/free
>>
>> T* p = (T*)malloc(sizeof T);
>
> When you need
>
> malloc(sizeof(T) + N)
>
> Allocators get a lot harder to use.

Agreed.

>
>> new(p) T();
>> ...
>> p->~T();
>> free(p);
>>
>> versus Boost UserAllocator
>>
>> T* p = (T*)user_allocator::malloc(sizeof T);
>> new(p) T();
>> ...
>> p->~T();
>> user_allocator::free(p);
>>
>> versus standard Allocator
>>
>> Allocator::pointer p = allocator.allocate(sizeof T);
>> allocator.construct(p,T());
>> ...
>> allocator.destroy(p);
>> allocator.deallocate(sizeof T);
> ^^^^^^^^
>
> Oops! There's a pointer missing here.

Silly me for not compiling my email.

> Just a small example of why I'm saying it's a harder interface.

Very small.

> Allocator has strange requirements, like "p shall not be null".

Another performance optimization. In most cases there is no way
that p could be null in the first place, so why waste time checking?

> If I need to build a custom one I have to
> navigate rebind and the implications of allocator inequality for which
> the standard provides little guidance.

Agreed. The Boost UserAllocator is easier to implement and to use.