tags:

views:

54

answers:

1

The STL allocators require this constructor form (20.1.5): X a(b); with the requirement that Y(a) == b;

In the standard implementation this implies, and is implemented as:

  template<class U> allocator( const allocator<U> & o ) throw()

I'm having trouble understanding why this requirement exists. I understand that allocators should be static (not have any state), but why on earth should you be able to convert them like this?

+4  A: 

To allow construction from other allocators, as containers need to use a different allocator type than you specify. Lists and maps, for example, allocate their internal node type rather than the value_type they expose.

The code looks similar to:

template<class T, class Alloc=std::allocator<T> >
struct Container {
  typedef T value_type;
  typedef Alloc allocator_type;

private:
  struct Node {/*...*/};
  typedef typename Alloc::template rebind<Node>::other RealAllocatorType;
  RealAllocatorType allocator;
};
Roger Pate
Only containers that store all items contiguously (vector, string) can use the given allocator type directly.
Roger Pate
Thanks. That is a really crappy requirement. I'm starting to agree with Scott Meyer here, the allocator system seems to be basically garbage.
edA-qa mort-ora-y
@edA: Like so many nights out on the town, it made sense 15 years ago. I agree today. :)
Roger Pate
Don't suppose fixing it is part of C++0x?
edA-qa mort-ora-y
@edA: I don't believe there's consensus on a system that would, counting the loss of backward compatibility, be overall better. But to be fair, I haven't followed what's been proposed to the committee and have been concentrating on the 0x drafts. Plus the current system does work for most uses — you might be interested in the [EASTL doc](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html).
Roger Pate
Well, what I consider a basic case doesn't work. I just want a private object pool for items created within a particular container. I have concurrent threads, so it simply isn't allowed that they share memory. I'll check out the EASTL.
edA-qa mort-ora-y
My more specific followup then is how to do this? http://stackoverflow.com/questions/4062682/how-to-create-an-allocator-for-stdmap-using-a-pool-of-objects
edA-qa mort-ora-y
@edA: As you point out in the question, the allocators shouldn't have any state. Use thread-local storage or a pointer in each allocator object to the memory pool: the allocators merely become a type-specific interface to that pool.
Roger Pate
I'm kind of doubting that I'd be able to write a generic memory pool that outperforms glibc malloc. Unless I can use an object based pool I don't think I'll get any useful gains.
edA-qa mort-ora-y
@edA: You can, of course, use malloc to implement the pool type.
Roger Pate