3

This question is more of a curiosity than a practical question.

In C++, many containers are "noded based". Meaning that for storage, they can't really use the allocator passed to them, instead, they do something like:

typedef typename A::template rebind<node>::other node_allocator_type

and presumably creates a member of this type like this or similar:

node_allocator_type node_allocator;

To create an allocator that can allocate nodes. Great, this all makes sense, but I have a question about what happens during a copy/move of the container if the container is truly "allocator aware", supporting stateful allocators.

Does the node allocator get copied/moved too? That makes sense on a surface level, but what happens when we hit a copy/move-constructor where the user can specify a new allocator like these?

list( const list& other, const Allocator& alloc );
list( list&& other, const Allocator& alloc );

In this case, the other's allocator isn't copied or moved, so does the newly constructed list get a brand new node_allocator along with it's copied/moved alloc?

This is obviously an implementation detail, but I'm curious about what is "right" and what typical implementations do. I also recognize that pre-C++11, stateful allocators weren't terribly well supported, and thus this was a non-issue.

Evan Teran
  • 87,561
  • 32
  • 179
  • 238

1 Answers1

1

The assumption is that copy-constructing allocators (even stateful allocators) is a cheap operation; if they have any associated resources they should be held by reference. Furthermore rebound allocators may be constructed by copy, and these compare equal to the original allocator; see a == b in Cpp17Allocator requirements.

The upshot of this is that the container is entirely at liberty to store an Allocator, an Allocator::rebind<void>, or an Allocator::rebind<node_type>, and to copy-convert between them as necessary when allocating nodes, on move construction, on (prvalue!) return from get_allocator(), etc. Generally libstdc++ stores an Allocator::rebind<node_type>, for example.

ecatmur
  • 152,476
  • 27
  • 293
  • 366