Имеет ли std :: vector * возможность * перемещать объекты при увеличении емкости? Или могут ли распределители «перераспределить»?
A другой вопрос вдохновил следующую мысль:
Есть лиstd::vector<T>
имеют переместить все элементы, когда он увеличивает свою емкость?
Насколько я понимаю, стандартное поведение заключается в том, что нижележащий распределитель запрашивает весь кусок нового размера, затем перемещает все старые элементы, затем уничтожает старые элементы и затем освобождает старую память.
Такое поведение представляется единственно возможным правильным решением с учетом стандартного интерфейса распределителя. Но мне было интересно, имеет ли смысл изменить распределитель, чтобы предложитьreallocate(std::size_t)
функция, которая будет возвращатьpair<pointer, bool>
и может отображаться в основнойrealloc()
? Преимущество этого состоит в том, что в случае, если операционная система может простопростираться выделенная память, тогда никакого перемещения вообще не должно произойти. Логическое значение будет указывать, переместилась ли память.
(std::realloc()
Возможно, это не лучший выбор, потому что нам не нужно копировать данные, если мы не можем расширить. Так что на самом деле мы бы предпочли что-то вродеextend_or_malloc_new()
. Редактировать: Возможноis_pod
специализация на основе признаков позволит нам использовать фактическоеrealloc
включая его побитовую копию. Просто не в общем.)
Это похоже на упущенную возможность. В худшем случае, вы всегда можете реализоватьreallocate(size_t n)
какreturn make_pair(allocate(n), true);
так что не будет никакого штрафа.
Есть ли проблема, которая делает эту функцию неуместной или нежелательной для C ++?
Возможно, единственный контейнер, который может воспользоваться этимstd::vector
, но опять же, это довольно полезный контейнер.
Обновление: маленький пример для уточнения. токresize()
:
pointer p = alloc.allocate(new_size);
for (size_t i = 0; i != old_size; ++i)
{
alloc.construct(p + i, T(std::move(buf[i])))
alloc.destroy(buf[i]);
}
for (size_t i = old_size; i < new_size; ++i)
{
alloc.construct(p + i, T());
}
alloc.deallocate(buf);
buf = p;
Новая реализация:
pair<pointer, bool> pp = alloc.reallocate(buf, new_size);
if (pp.second) { /* as before */ }
else { /* only construct new elements */ }