|
Boost : |
From: Gregory Colvin (gregory.colvin_at_[hidden])
Date: 2003-09-02 13:05:58
On Tuesday, Sep 2, 2003, at 11:22 America/Denver, David Abrahams wrote:
> Gregory Colvin <gregory.colvin_at_[hidden]> writes:
>
>> On Tuesday, Sep 2, 2003, at 09:22 America/Denver, David Abrahams
>> wrote:
>>
>>> 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
>>> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-closed.html#390
>>
>> So you would rather use this than use construct?
>>
>> template <typename T> T* addressof(T& v)
>> {
>> return reinterpret_cast<T*>(
>> &const_cast<char&>(reinterpret_cast<const volatile char
>> &>(v)));
>> }
>
> As long as it's packaged away and I don't have to look at the
> implementation. A customization point like an allocator should not be
> required to supply boilerplate that's always going to be the same.
You are assuming that there was no good reason to allow an allocator
to hook construct and destroy, for instance to do some bookkeeping.
> When I need to find out what I need to implement in order to customize
> allocation, I don't want to have to read through something which is
> 50% irrelevant to the task, as the allocator requirements are.
Which is why I'm now suggesting that Boost UserAllocator is a better
default.
But in some cases, like the shared_ptr feature request that got me
thinking on this, what you want is just to have objects allocate
their internals using the same allocator as the container they
are being placed in, in which case you don't need to implement an
allocator, just call get_allocator().
>>>>> n 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.
>>
>> In which case the A::pointer return from A::allocate() is already
>> undefined behavior?
>
> Wow. Yes, IIUC. DR, I guess.
I'm reeling from the implication that the following is undefined
behavior for non-POD T:
T* p = (T*)malloc(sizeof T);
Are you sure?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk