Есть ли C ++ распределитель, который учитывает переопределенные новые / удаления? - PullRequest
11 голосов
/ 19 октября 2011

Я реализую операцию клонирования с выделением ресурсов для массива типа 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спецификация).Меня беспокоит то, что подход на основе std::allocator кажется неправильным для типов T, где T::operator new был определен.Я знаю, что могу обнаружить такую ​​ситуацию, используя Boost.TypeTraits 'has_new_operator.

. Существует ли простой, совместимый со стандартами способ выделения и последующей инициализации необработанной памяти способом, который будет учитывать переопределеннуюновый (и делает ли так, что передача по памяти только один раз)?Если нет, то кажется ли разумным использование SFINAE для диспетчеризации между реализацией, использующей std::allocator, и реализацией, использующей переопределенный оператор new?FWIW, просмотр через Boost не показывает такого использования черты has_new_operator.

Спасибо, Рис

Ответы [ 2 ]

4 голосов
/ 19 октября 2011

Кажется, это невозможно.Только operator new[] знает, как хранить размер массива (если у T есть деструктор) каким-то образом, зависящим от реализации (operator delete[] использует эту информацию).Следовательно, нет переносимого способа хранения этой информации без нового выражения (и без вызова конструкторов элементов).

1 голос
/ 25 ноября 2011

попробуйте размещение нового тогда.

    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
    }
...