Jared Hoberock
Jared Hoberock

Reputation: 11406

Why are std::allocator::construct and std::allocator::destroy templated on element type?

std::allocator's construct and destroy member functions are parameterized on the type of the element to construct:

template<class T>
  class allocator
{
  public:
    typedef T value_type;
    typedef T* pointer;

    template<class U, class... Args>
      void construct(U *p, Args&&... args);

    template<class U>
      void destroy(U *p);

  ...
};

What's the rationale for this? Why don't they take either value_type* or pointer? It seems like allocator<T> should only know how to construct or destroy objects of type T.

Upvotes: 8

Views: 1199

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473477

It's for the same reason that allocators are required to have the rebind<U> typedef: because many containers never allocate Ts.

Take linked lists. These allocate nodes, each one of which contains a T as a member. So allocators are required to be able to allocate some type that they don't know of (via rebind<U>). However, that requires a copy operation: it requires creating a new allocator of the type rebind<U>::other.

It's better to avoid that when possible. Therefore, for construction and destruction, allocators are required to do the appropriate operations on any type, such as the linked list's internal node types. This also makes it possible for the linked list's internal node type to have Allocator::construct/destruct as friend functions.

Upvotes: 16

Related Questions