2013-02-10 6 views
5

Per quanto ho capito, la motivazione alla base di deque è quella di fornire un contenitore ad accesso casuale con efficienza push_front.Perché std :: deque non è un vettore con memoria riservata prima dell'indice 0?

Vantaggi del vettore comunemente citati rispetto a deque include traversal più veloce e at(), ma soprattutto la sua compatibilità con C, in quanto garantisce memoria contigua. Deque no, dal momento che è una raccolta di blocchi di memoria, ognuno dei quali contiene un numero di valori.

Sono confuso. Perché la deque non è costruita come un vettore ma con la memoria riservata prima dell'indice 0 oltre alla memoria riservata dopo l'indice size-1? Ciò garantirebbe memoria contigua, abilitare l'efficienza push_front ed evitare anche l'indirezione aggiuntiva durante la dereferenziazione degli iteratori.

Per ridurre al minimo lo spostamento durante l'inserimento, i valori contenuti da spostare dipenderanno dal punto di inserimento. Se si inserisce l'indice n prima del size()/2, spostare i valori fino a n a sinistra. Altrimenti spostare i valori a destra dopo n.

Che cosa mi è mancato è così importante che deque è una raccolta di matrici di valori e non un unico grande array?

+0

costo ammortizzato, forse? Il veloce 'push_front' non è l'unico requisito per' deque' –

+1

E quanta memoria riserveresti? 1 KB, 10 KB, 1 M, 1 GB, 24 GB? Qualunque cosa tu faccia, qualcuno si lamenterà che è troppo o non abbastanza ... –

+0

Afaik è così che Qt implementa la sua QList – BeniBela

risposta

8

According to Wikipedia, quello che stai descrivendo è davvero una possibile implementazione, almeno in generale.

Tuttavia, lo standard C++ impone requisiti che lo vietano essenzialmente come implementazione per std::deque; [deque.modifiers] afferma:

Un inserimento alle due estremità del deque ... non ha alcun effetto sulla validità dei riferimenti agli elementi del deque.

(Grazie a @BenjaminLindley!)

+0

I STFW per una risposta, ma Wikipedia di solito non mi viene in mente per questi argomenti (: – Gabriel

+4

23.3.3.4/1 e/4 dice che l'inserimento o la rimozione alle estremità del deque non invaliderà i riferimenti. essere possibile se il deque ha funzionato in questo modo (ho già detto gli iteratori, ma sono solo riferimenti) –

+0

Quindi le implementazioni che si basano su memoria contigua con reallocs non sono conformi agli standard? Suppongo che altre implementazioni possano fornire la compatibilità con un 'c_array' funzione, molto simile a 'stringa :: c_str', che reimballerebbe tutti i blocchi in uno grande e sarà invalidato dagli inserti. – Gabriel

Problemi correlati