perché i contenitori STL usano la copia da popolare in ridimensionamento?

tutti i contenitori STL che implementano il resize utilizzano copie per popolare i nuovi elementi anche se l’origine della copia è un object predefinito costruito?

Perché è fatto in questo modo?

Non vedo alcun vantaggio e alcuni costi.


Come contesto, l’ho trovato mentre cercavo un contenitore ad accesso casuale per elementi che non possono essere copiati :

Salva sulla complessità. Abbiamo certamente bisogno del caso di costruzione della copia e la costruzione di default può essere modellata come replica di un object costruito di default.

La penalità di prestazione è trascurabile. Scrivere zero significa circa la stessa velocità della copia degli zeri. La sanzione della compatibilità è nullo poiché tutti i contenitori richiedono comunque la riproducibilità. La costruzione predefinita invece non è richiesta.

Se vuoi davvero utilizzare contenitori standard con oggetti non copiabili, guarda in C ++ 0x e nella costruzione sul posto con emplace . Tuttavia, non esiste un metodo per emplace più elementi contemporaneamente. (Se stai usando deque , non ci dovrebbe essere molta penalizzazione delle prestazioni per un ciclo di emplace o di resize ).)

Nel tuo caso, forse sarebbe meglio archiviare i puntatori a quegli oggetti nel contenitore: un puntatore può essere copiato.

Per quanto riguarda la copia in un contenitore; qual è l’alternativa? Se hai dovuto ridistribuire un nuovo blocco di memoria per archiviare ciò che è stato archiviato, devi ottenere i dati esistenti in qualche modo!

L’unica ragione per cui posso pensare a questo comportamento è che i contenitori supportano l’inserimento e l’inserimento richiede una copia. Dovresti essere in grado di creare un contenitore che supporti il ​​ridimensionamento in un modo simile a un deque (impaginato e non contiguo) che il default costruisce i nuovi elementi. Tuttavia, dovresti disabilitare l’assegnazione dell’intero contenitore insieme all’inserimento di elementi: potresti invece modificare gli oggetti costruiti nella raccolta.

La mia ipotesi è che nessuno abbia visto la necessità di una raccolta che non supporta l’inserimento e non implementa la copia di tipo valore. Come un’altra nota, dovresti probabilmente taggarla come wiki prima che venga chiusa;)

I contenitori standard definiscono i requisiti CopyConstructible e Assignable sul tipo di valore, e tali requisiti sono sufficienti per supportare tutte le operazioni su contenitori e sequenze (potreste anche volere che siano comparabili per contenitori associativi, ma anche questo non è necessario poiché è ansible invece di fornire un comparatore).

Quello che stai chiedendo è di avere una serie di requisiti per un insieme di operazioni costituito da una parte del Container più qualcosa da Sequence (vale a dire 1 parametro resize() su quei contenitori che non riposizionano mai il loro contenuto, operator[] , clear() e l’interfaccia iteratore escludendo *it = t ) e un’altra serie di requisiti per il resto. Le librerie standard preferiscono fare ciò al contrario: scegliere un insieme comune di requisiti che coprono quasi tutto e quindi avere requisiti aggiuntivi per piccoli bit di funzionalità (come il requisito di essere costruttibili in modo predefinito per chiamare resize() senza specificando il secondo parametro).

I contenitori non sono stati concepiti con il tuo specifico insieme di operazioni in mente – la copia e l’assegnazione sono intrinseche a ciò che sono progettate per fare, che consiste nel contenere i valori che vengono inseriti in esse, quindi suppongo che nella mente di Stepanov ciò non sia un “piccolo po ‘di funzionalità”. Quindi i requisiti più ampi ci sono perché il contenitore di astrazione è più grande del tuo proposto ResizeableCollectionOfDefaultConstructedObjects. In effetti, togliere resize() e CollectionOfDefaultConstructedObjects è praticamente solo un array. Immagino che i progettisti del STL e dello standard C ++ non incontrassero il tuo caso d’uso abbastanza spesso da pensare che valesse la pena di astrarre.