For a user-defined allocator, the relation between the allocated-units must be constructed at the beginning, while the memory space for elements should be left uninitialized.
A simple demo:
template <typename T>
struct Node {
T _item;
Node* _prev;
Node* _next;
};
template <typename T, typename ParentAllocator>
class MyAllocator {
using Allocator = std::allocator_traits<ParentAllocator>::rebind_alloc<Node<T>>;
Allocator _allocator;
Node<T> _header;
/* ... */
public:
MyAllocator()
: _allocator()
{
_header._prev = &_header;
_header._next = &_header;
// leaving `_item` uninitialized
}
T* allocate(/*one*/) {
auto* newNode = _allocator.allocate(1);
newNode->_prev = &_header;
newNode->_next = _header._next;
// leaving `_item` uninitialized
/* ... */
return &(newNode->_item);
}
};
Node
is not initialized, instead direct initialization for its members, though not for all.
My questions are:
- Are
_header
and_next
really partially initialized as expectations, even if the default constructor ofT
(both normal andexplicit
one) were deleted. - Have I implemented it properly?
- If not, what's the right way?