How to allocate a non-copyable object with a custom allocator?

J

Juha Nieminen

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);
alloc.construct(ptr, Type(5));

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?
 
P

peter koch

  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);
    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).
  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?

To repeat myself: placement new.

/Peter
 
J

James Kanze

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.
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 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top