allocator_traits::construct() vs allocator_traits::allocate()
c++, c++11, memory-management
Solution
There are two techniques to do this depending on what you have at the moment.
If you have an lvalue expression, say the value field in a node, then you can use std::addressof like so:
allocator_traits<allocator_type>::construct(alloc, std::addressof(ptr->value), ...);
where `ptr` is an `allocator_type::pointer`.
However if you don't have a field to dereference and you want to convert an `allocator_type::pointer` to `T*`, there's a trick you need to implement first:
template <class T>
inline
T*
to_raw_pointer(T* p) noexcept
{
return p;
}
template <class Pointer>
inline
typename std::pointer_traits<Pointer>::element_type*
to_raw_pointer(Pointer p) noexcept
{
return p != nullptr ? ::to_raw_pointer(p.operator->())
: nullptr;
}
And now you can say:
allocator_traits<allocator_type>::construct(alloc, to_raw_pointer(ptr), ...);
Problem
C++11 provides the `std::allocator_traits` class as the standard way to use allocators. The static function `std::allocator_traits::construct()` takes a pointer to where the object should be constructed. The `std::allocator_traits::allocate()` static function, however, returns an `allocator::pointer` value, which only has to behave like a pointer but it is not necessarily one (in general, although `std::allocator::pointer` is required to be a pointer). How is one supposed to use the allocation and construction static methods if, in general, they will work with incompatible types? Can they be used only if the `pointer` type is actually convertible to a normal plain pointer?