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);
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.