Search code examples
c++shared-ptrallocator

is allocator_traits::deallocate a valid shared_ptr deleter


I guess this question is really about the design of std::allocator_traits and providing a custom allocator. If I want to construct a std::shared_ptr<> using a custom allocator, can I use std::allocator_traits?

Basically, is this correct?

WidgetAllocator allocator;
std::shared_ptr<Widget> widget(allocator.allocate(), std::allocator_traits<WidgetAllocator>::deallocate);

Solution

  • Basically, is this correct?

    std::shared_ptr<Widget> widget(allocator.allocate(), std::allocator_traits<WidgetAllocator>::deallocate);
    

    That's not correct.

    Firstly, an allocator is not guaranteed to have a nullary allocate member function.

    OK, let us assume that WidgetAllocator does provide such overload, although that's not quite typical for an allocator. But more importantly, std::allocator_traits::deallocate is not callable with a Widget*. Its argument list is ( Alloc& a, pointer p, size_type n ).

    So what's the recommended use of allocator_traits?

    You should use std::allocator_traits whenever you want to use one of the optional features of an allocator such as Alloc::is_always_equal, and the allocator that you want to use either does not provide the optional feature, or the allocator is a template argument, and you want to support all allocators regardless of whether they provide optional features.

    std::allocator_traits provides default implementation for the optional features of an allocator.

    Should I be invoking methods on the allocator directly?

    You can invoke member functions directly, if the allocator that you use provides them, or in generic case, if they are non-optional. Invoking the members directly is not necessary though, you can always use allocator traits instead.