Я собираюсь создать собственный распределитель, предварительно распределяя большой блок (массив) для хранения элементов N
некоторого класса T
, а затем просто увеличивайте индекс внутри массива до запросов на распределение ресурсов.
Так как я не хочу инициализации для элементов в предварительно выделенном блоке, что-то вроде этого не будет работать:
T buffer[N];
потому что в этом случае конструктор T
будет вызываться для элементов N
блока.
Поскольку я понимаю, что std::aligned_storage
не вызывает конструктор T
, я думал об использовании std::aligned_storage
, что-то вроде этого:
std::aligned_storage<
N * sizeof(T),
std::alignment_of<T>::value
>::type buffer;
T* base = static_cast<T*>( static_cast<void*>(&buffer) );
И тогда распределитель может просто увеличивать базовый указатель, когда запрашивается выделение для Т (до (base+N)
), а Т можно построить на месте (с размещением new
), когда это необходимо.
Я хотел бы использовать эту схему для определения пользовательского распределителя для контейнеров STL. Однако мне кажется, что здесь может возникнуть проблема для переподключения. На самом деле, если мое понимание правильное, распределитель STL должен поддерживать восстановление из типа T
в тип U
, например. потому что контейнеры, такие как std::list<T>
(или другие контейнеры на основе node, такие как std::map
), используют распределители для выделения узлов, которые на самом деле не имеют тип T
, но другого типа U
(содержащий T
и другие "заголовка" для node).
Итак, применил бы вышеупомянутый подход std::aligned_storage
для перезаписи? Или (как я думаю) правильное выравнивание для T
не означает правильного выравнивания для другого другого типа U
?
Как решить эту проблему?
Как я могу определить вышеупомянутый buffer
, чтобы он работал и для перезаписи на другой тип U
?
Если эта проблема будет атакована с другой точки зрения? Если да, то что?