On Sep 4, 7:29 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 4 Sep., 16:35, Juha Nieminen <nos...@thanks.invalidwrote:
If we have a custom allocator (eg. given to us as a template
parameter), the proper way of allocating an object using it
is like:
Allocator alloc;
Allocator::pointer ptr = alloc.allocate(1);
I saw that parameter before, but decided not to comment on it.
The standard way to allocate is to specify the size of the
object, so "tradition" should prescribe alloc.allocate(sizeof
Type);
Not according to the C++ standard.
alloc.construct(ptr, Type(5));
No - that is not the way. You use placement new. (Also: the
allocated data should be a pointer to void).
Placement new is another alternative, but the standard requires
the above for standard containers (and presumably, for user
defined containers which are meant to be "similar" to standard
container).
The problem with this is that it requires 'Type' to have a
copy constructor. It might not have one (ie. it might be
disabled). Having the copy constructor disabled doesn't stop
an object from being allocated with 'new'. But how to
allocate it with an allocator?
The obvious answer is that you can't. A container cannot be
made to work without some sort of publicly available
constructor, and the choice of the standard library was that
this should be the copy constructor (and not e.g. the default
constructor).
To repeat myself: placement new.
Not if you want your container to be "standard-like". In
practice, I don't normally offer an Allocator parameter for my
own containers; it doesn't seem worth the effort. But Juha
apparently wants to, and he's doing the right thing if that's
what he wants. Of course, if he wants to write "standard-like"
container, he can't require a default constructor, so the only
constructor he has available is the copy constructor.
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34