There is a template parameter for STL containers to chose a custom allocator. It took a while, but I think I understand how it works. Somehow it isn\'t really nice because the g
The type of the allocator used by a container is defined by its constructor argument: it is exactly this type which is expected in the container's constructors. However, any allocator needs to be able to serve different types than the one it is defined for. For example, for a std::list
the allocator expected is capable to allocate T
object but it will never be used to allocate these object because the std::list
actually needs to allocate nodes. That is, the allocator will be rebound to allocate a different type. Unfortunately, this makes it hard to use an allocator to serve a specific type: You don't know the type the allocator will actually serve.
With respect to scoped allocators it works quite straight forward: The container determines if it has any member with a constructor taking a matching allocator. If this is the case, it will rebind the allocator it used and passes this allocator to the member. What isn't that straight forward is the logic determining whether an allocator is being used. To determine if a member uses an allocator, the traits std::uses_allocator
is used: It determines if T
has a nested typedef allocator_type
which and if A
can be converted to this type. The rules for how member objects are constructed are described in 20.6.7.2 [allocator.uses.construction].
In practice this means that allocators are useful for dealing with a pool used for a container and its members. In some contexts it may also work reasonable when similar sized objects are allocated, e.g. for any of the node based containers, to keep a pool of equal sized objects. However, it isn't necessary clear from the pattern used with allocator if they are, e.g., for the nodes or some strings contained with. Also, since the use of different allocation policies would change the type, it seems most reasonable to either stick with the default allocation or to use an allocator type which is a proxy for a polymorphic allocator actually defining the allocation policy. Of course, the moment you have stateful allocators, you may have objects with different allocators and e.g. swap()
ing them might not work.