简体   繁体   中英

What does the std::list do with its allocator argument?

std::list is parameterized by an allocator type, which it presumably rebinds in order to allocate list nodes rather than T s. So what does it do with the object of allocator type passed to the constructor?

template <class T, class Alloc = std::allocator<T>>
class list
{
    class node { ... T element; ... };

    using real_alloc =
        typename std::allocator_traits<Alloc>::template rebind_alloc<node>;
    real_alloc m_allocator;

public:
    list(const Alloc&);
};

In the above code, we need to initialize m_allocator to a node allocator, but the constructor is given a T allocator. Do we just drop the T allocator on the floor, or do we use it somehow?

Since C++11 allocators can be stateful. You want to construct your internal allocator using the user supplied one. An Allocator is explicitely required to be constructible from typename std::allocator_traits<Alloc>::template rebind_alloc<U> .

Implementations of list constructor should look like this:

template<class T, class Alloc>
class list
{
      struct node_type {/*etc*/}; //internal
      using allocator_type_internal = typename std::allocator_traits<Alloc>::template rebind_alloc<node_type>;
      // etc.
      allocator_type_internal m_allocator; //Note we use allocator_type, not Alloc.
};

list::list(const Alloc& alloc ) : 
     m_allocator(alloc)
{ /* initialize sentinel node, etc. */ }

Although a good implementation would use empty-base optimization for the allocator.

The T allocator is still used to construct() and destroy() the T portion of the internal nodes. Using these operations may be necessary to add custom arguments during construction, eg, optionally forward a suitable allocator argument to the constructed objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM