Std :: vector * have * per spostare oggetti durante la crescita della capacità? Oppure, gli allocatori possono “riallocare”?

Una domanda diversa ha ispirato il seguente pensiero:

std::vector deve spostare tutti gli elementi quando aumenta la sua capacità?

Per quanto ho capito, il comportamento standard è che l’allocatore sottostante richieda un’intera parte della nuova dimensione, quindi sposta tutti i vecchi elementi, quindi distrugge i vecchi elementi e quindi rilascia la vecchia memoria.

Questo comportamento sembra essere l’unica soluzione corretta data l’interfaccia standard di allocatore. Ma mi stavo chiedendo, avrebbe senso modificare l’allocatore per offrire una funzione di reallocate(std::size_t) che restituirebbe una pair e potrebbe mappare al realloc() sottostante realloc() ? Il vantaggio di ciò sarebbe che, nel caso in cui il sistema operativo possa effettivamente estendere la memoria allocata, non dovrebbe accadere alcun movimento. Il valore booleano indica se la memoria è stata spostata.

( std::realloc() forse non è la scelta migliore, perché non abbiamo bisogno di copiare i dati se non possiamo estenderli, quindi in effetti preferiremmo qualcosa come extend_or_malloc_new() . Edit: Forse a is_pod -trait- la specializzazione basata ci permetterebbe di usare il realloc reale, inclusa la sua copia bit a bit. Giusto non in generale.)

Sembra un’occasione persa. Nel peggiore dei casi, si può sempre implementare la reallocate(size_t n) come return make_pair(allocate(n), true); , quindi non ci sarebbe alcuna penalità.

C’è qualche problema che rende questa funzione inappropriata o indesiderabile per C ++?

Forse l’unico contenitore che potrebbe trarne vantaggio è std::vector , ma di nuovo è un contenitore abbastanza utile.


Aggiornamento: un piccolo esempio per chiarire. resize() corrente 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; 

Nuova implementazione:

 pair pp = alloc.reallocate(buf, new_size); if (pp.second) { /* as before */ } else { /* only construct new elements */ }