Есть ли распределитель С++, который уважает переопределенное новое/удаление?
Я реализую операцию клонирования выделения ресурсов для массива типа T
. В простой реализации используется new T[sz]
, за которой следует вызов std::copy
из источника в новый массив. Он дважды просматривает память.
Я хотел бы выделить необработанную память, а затем использовать std::uninitialized_copy
, поэтому я просто занимаюсь памятью один раз по соображениям производительности. Я знаю, как это сделать, когда используется пользовательский распределитель (Allocator.allocate
, а затем std::uninitialized_copy
), и я знаю, как это сделать, используя std::allocator
(который использует ::operator new
после lib.allocator.members
в разделе 20.4.1.1 спецификация). Моя забота заключается в том, что подход <<26 > кажется неправильным для типов T
, где T::operator new
определено. Я знаю, что могу обнаружить такую ситуацию, используя Boost.TypeTraits 'has_new_operator
.
Существует ли простой, стандартизованный способ выделения и затем инициализации необработанной памяти таким образом, который будет уважать переопределенное новое (и делает ли это передачу памяти только один раз)? Если нет, использует SFINAE для отправки между реализацией, использующей std::allocator
, а другой с использованием переопределенного оператора new, как представляется, разумным? FWIW, grepping through Boost не показывает такого использования признака has_new_operator
.
Спасибо,
Риз
Ответы
Ответ 1
Кажется, это невозможно. Только operator new[]
знает, как сохранить размер массива (если T
имеет деструктор) по определенному пути реализации (operator delete[]
затем использует эту информацию). Поэтому нет переносного способа хранения этой информации без нового выражения (и без конструкторов вызывающих элементов).
Ответ 2
попробуйте установить новое место.
typedef std::string T;
T src[5];
char* p = new char[sizeof(T)* 5];
T* dest = (T*)p;
for(int i = 0;i < 5; ++i)
{
new(dest + i) T(src[i]); //placement new
}