std :: dynarray vs std :: vector


84

C ++ 14 presenta std::dynarray:

std :: dynarray è un contenitore di sequenze che incapsula array con una dimensione che è fissata alla costruzione e non cambia per tutta la durata dell'oggetto.

std::dynarraydeve essere allocato in fase di esecuzione come lo stesso std::vector.

Quindi quali sono i vantaggi e l'utilizzo di std::dynarraywhile possiamo usare std::vectorche è più dinamico (e anche ridimensionabile)?


1
Ehi, da quando "C ++ 14" è un tag? Lo stavo cercando l'altro giorno e non esisteva ...
Kerrek SB

1
Viene std::valarrayrinominato come std::dynarray? Che cosa è dinamico std::dynarrayquando non può essere ridimensionato?
yasouser

9
@yasouser, no, non ha niente a che fare con valarray. È dinamico perché la lunghezza dell'array è un valore di runtime, non è necessario che sia noto in fase di compilazione, a differenza distd::array
Jonathan Wakely

21
Si noti che alla riunione del Comitato per gli standard C ++ la scorsa settimana, è dynarraystato rimosso da C ++ 14 e inserito in una specifica tecnica futura (pensatela come una nuova versione di TR1) perché ha alcuni seri problemi tecnici.
Pete Becker

2
dynarray non fa più parte della bozza C ++ 14
cassinaj

Risposte:


90

Quindi quali sono i vantaggi e l'utilizzo di std::dynarray, quando possiamo usare std::vectorquale è più dinamico (ridimensionabile)?

dynarray è più piccolo e più semplice di vector , perché non ha bisogno di gestire valori separati di dimensione e capacità e non ha bisogno di memorizzare un allocatore.

Tuttavia, il principale vantaggio in termini di prestazioni dovrebbe derivare dal fatto che le implementazioni sono incoraggiate ad allocare dynarraysullo stack quando possibile, evitando qualsiasi allocazione di heap. per esempio

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

Questa ottimizzazione richiede la collaborazione del compilatore, non può essere implementata come un puro tipo di libreria e la necessaria magia del compilatore non è stata implementata e nessuno è sicuro di quanto sia facile da fare. A causa della mancanza di esperienza nell'implementazione, alla riunione del comitato C ++ a Chicago la scorsa settimana è stato deciso di tirare std::dynarrayda C ++ 14 e di emettere un documento separato per le estensioni di array TS (specifica tecnica) std::experimental::dynarraye gli array di runtime bound (ARB, simili a VLA C99.) Questo significa std::dynarrayche quasi certamente non sarà in C ++ 14.


1
Grande, mi chiedevo se ci fossero eventuali implementazioni non banali dynarrayin natura. Ho sempre pensato che avessi bisogno di due implementazioni indipendenti della pratica esistente prima che qualcosa diventi idoneo per la standardizzazione.
Kerrek SB

No, non ci sono implementazioni note di un'allocazione dello stack dynarray. Sebbene l'esperienza di implementazione sia molto utile, non esiste una regola fissa che lo richieda (ma alcuni direbbero che dovrebbe esserci!)
Jonathan Wakely

solo brainstorming qui, ma per quanto riguarda la creazione di 2 funzioni: std :: dynarray make_dyn_autostorage (int) e std :: dynarray make_dyn_heap (int)?
Servire Laurijssen

2
@KerrekSB, sì, il movimento della libreria 10 a Chicago era: "Spostiamo creiamo un documento di lavoro per un TS di estensioni di array pianificato, rimuoviamo le modifiche applicate al CD C ++ 14 dai due documenti N3639 ," Array di dimensioni runtime con automatico durata della memorizzazione (revisione 5) " N3662 ," C ++ Dynamic Arrays (dynarray) "e indicare all'editor del progetto Array Extensions TS di applicare tali parole all'Array Extensions Working Paper come contenuto iniziale."
Jonathan Wakely

3
@ h9uest che non ha niente a che fare con "i ragazzi del C ++", quelli sono i nomi ufficiali per i risultati di un comitato tecnico ISO , vedere iso.org/iso/home/standards_development/… e iso.org/iso/home/standards_development /…
Jonathan Wakely

31

Come hai detto tu stesso, std::dynarrayè per un array dinamico di dimensioni fisse . Non è ridimensionabile. Più o meno parlando, è un miglioramento ancora new T[N]e ancora std::unique_ptr<T[]>(new T[N]).

Non aver bisogno di ridimensionare o gestire la capacità significa che puoi implementare la struttura dei dati con meno complessità e in meno spazio.

Inoltre, std::dynarrayè un animale strano che consente all'implementazione di implementarlo in modi diversi e non specifici, ad esempio è possibile mettere l'array in pila. La chiamata a una funzione di allocazione è "opzionale". È possibile specificare un allocatore per costruire gli elementi dell'array, ma questo non fa parte del tipo.

Si potrebbe anche chiedere perché abbiamo bisogno std::dynarray e gli array di lunghezza variabile. I VLA in C ++ 14 sono molto più restrittivi; possono essere solo variabili locali e automatiche e non offrono alcun modo per specificare una politica di allocazione e, naturalmente, non hanno un'interfaccia contenitore standard.


Alcuni esempi dal 23.3.4.2 di una "bozza corrente" (prendilo, cache di Google):

explicit dynarray(size_type c);

Effetti: alloca lo spazio di archiviazione per gli celementi. Può o non può invocare il globale operator new.

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

Effetti: equivalente ai costruttori precedenti tranne per il fatto che ogni elemento è costruito con la costruzione dell'allocatore degli usi .

O se non si può utilizzare un dato allocatore per costruire gli elementi della matrice è un tratto globale:

struttura del modello usa_allocatore, Alloc>: true_type {};

Richiede: Alloc deve essere un allocatore (17.6.3.5). [ Nota: la specializzazione di questo tratto informa altri componenti della libreria che dynarraypossono essere costruiti con un allocatore, anche se non dispone di un allocator_type nidificato.]

Modifica: la risposta di Jonathan Wakely è destinata ad essere molto più autorevole e perspicace.


Il passaggio di un allocatore al dynarraycostruttore di non è mai usato per l'allocazione, è usato solo come argomento per i costruttori degli elementi (usando la "costruzione usa-allocatore"). Ecco perché non è possibile interrogare se è stato utilizzato l'allocatore: perché non lo è mai.
Jonathan Wakely

@ JonathanWakely: Ah, l'ho capito male. Grazie, risolto!
Kerrek SB
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.