Std :: vector * tem * para mover objetos ao aumentar a capacidade? Ou, os alocadores podem "realocar"?
A different question inspirou o seguinte pensamento:
Fazstd::vector<T>
te mover todos os elementos quando aumentar sua capacidade?
Pelo que entendi, o comportamento padrão é que o alocador subjacente solicite um pedaço inteiro do novo tamanho, mova todos os elementos antigos, destrua os elementos antigos e desaloque a memória antig
Este comportamento parece ser a única solução correta possível, dada a interface padrão do alocador. Mas eu queria saber, faria sentido alterar o alocador para oferecer umreallocate(std::size_t)
função que retornaria umpair<pointer, bool>
e pode mapear para o @ subjacenrealloc()
? A vantagem disso seria que, no caso de o sistema operacional poder apenasamplia na memória alocada, nenhum movimento teria que acontecer. O booleano indica se a memória foi movid
(std::realloc()
talvez não seja a melhor opção, porque não precisamos copiar dados se não pudermos estender. Então, na verdade, preferimos algo comoextend_or_malloc_new()
. Editar Talvez umis_pod
especialização @ -trait nos permitiria usar orealloc
, incluindo sua cópia bit a bit. Apenas não em geral.)
Parece uma oportunidade perdida. Na pior das hipóteses, você sempre pode implementarreallocate(size_t n)
Comoreturn make_pair(allocate(n), true);
, para que não haja penalidade.
xiste algum problema que torne esse recurso inadequado ou indesejável para C +
Talvez o único contêiner que possa tirar proveito disso sejastd::vector
, mas, novamente, esse é um contêiner bastante úti
Update: Um pequeno exemplo para esclarecer. Atualresize()
:
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;
Nova implementação:
pair<pointer, bool> pp = alloc.reallocate(buf, new_size);
if (pp.second) { /* as before */ }
else { /* only construct new elements */ }