Для моего проекта я пишу несколько контейнеров STL с нуля (у меня есть свои причины). Поскольку я так близко имитирую функциональность и интерфейсы STL, я прилагаю все усилия, чтобы придерживаться политики «если у нее такое же имя, как у стандартной конструкции, она будет максимально соответствовать стандарту».
Так что, конечно, мои контейнеры принимают распределители в качестве параметра шаблона, что очень удобно, поскольку допускает некоторые пользовательские схемы размещения. На мой вопрос.
Интерфейс std::allocator
отделяет распределение памяти от построения объекта. Точно так же это отделяет освобождение от разрушения. Это имеет смысл, поскольку то, откуда вы получаете память, более или менее не имеет значения для правильного конструирования объекта в c ++.
Таким образом, есть две функции конструирования / освобождения, которые выглядят так для реализации по умолчанию (взяты прямо из книги):
void construct(pointer p, const T& val) { new(p) T(val); }
void destroy(pointer p) { p->~T(); }
Как вы можете видеть, конструкция просто вызывает размещение новых, а уничтожение просто вызывает деструктор.
Есть ли какая-либо причина использовать их, просто используя новый синтаксис и синтаксис деструктора? может ли «правильный» распределитель реализовать их по-другому? Или я гарантирую, что все реализации распределителя, которые соответствуют стандарту, будут иметь методы конструирования / уничтожения, реализованные таким образом?
Более конкретно, можно ли с уверенностью сказать, что я всегда могу использовать std::uninitialized_copy
и std::uninitialized_fill
для конструирования элементов моих контейнеров?
Спасибо.