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 given allocator type isn’t used directly but it is rebound to the allocator of another type. Finally I can work with it.
After reading the API I recognized that there is also the possibility to give allocators as constructor parameter. But how do I know which kind of allocator the container uses, if it internally rebinds the given allocator from the template parameter?
Additionally I read that C++11 now uses scoped allocators which allow to reuse the allocator of a container for its containing containers. How does the implementation of a scoped allocator enabled container roughly differs from one that is not aware of scoped containers?
Unfortunately I wasn’t able to find anything that could explain this. Thanks for answers!
Always supply an
Allocator<T>to the constructor (whereTis thevalue_typeof the container). The container will convert it to anAllocator<U>is necessary whereUis some internal data structure of the container. TheAllocatoris required to supply such converting constructors, e.g.:Well, to be more precise, C++11 has an allocator adaptor called
scoped_allocator_adaptor:From C++11:
So you only get the scoped allocators behavior if you specify a
scoped_allocator_adaptoras the allocator for your container.The key is that the container now deals with its allocator via a new class called
allocator_traitsinstead of dealing with the allocator directly. And the container must useallocator_traitsfor certain operations such as constructing and destructingvalue_types in the container. The container must not talk to the allocator directly.For example, allocators may provide a member called
constructthat will construct a type at a certain address using the given arguments:If an allocator does not provide this member,
allocator_traitswill provide a default implementation. In any event, the container must construct allvalue_types using thisconstructfunction, but using it throughallocator_traits, and not using theallocatordirectly:The
scoped_allocator_adaptorprovides customconstructfunctions whichallocator_traitswill forward to which take advantage of theuses_allocatortraits and passes the correct allocator along to thevalue_typeconstructor. The container remains blissfully ignorant of these details. The container only has to know that it must construct thevalue_typeusing theallocator_traits constructfunction.There are more details the container must have to deal with to correctly handle stateful allocators. Though these details too are dealt with by having the container not make any assumptions but get all properties and behaviors via
allocator_traits. The container can not even assume thatpointerisT*. Rather this type is found by askingallocator_traitswhat it is.In short, to build a C++11 container, study up on
allocator_traits. And then you get scoped allocator behavior for free when your clients use thescoped_allocator_adaptor.