2013-02-10 12 views
5

O ile rozumiem, motywem deque jest zapewnienie kontenerowi o swobodnym dostępie z wydajnym push_front.Dlaczego std :: deque nie jest wektorem z pamięcią zarezerwowaną przed indeksem 0?

Powszechnie wymieniane zalety wektora w porównaniu do deque obejmują szybsze przechodzenie i at(), ale głównie jego kompatybilność z C, ponieważ gwarantuje przyległą pamięć. Deque nie, ponieważ jest zbiorem fragmentów pamięci, z których każda ma wiele wartości.

Jestem zdezorientowany. Dlaczego deque nie jest zbudowany jak wektor, ale z pamięcią zarezerwowaną przed indeksem 0 oprócz pamięci zarezerwowanej po indeksie size-1? Zapewniłoby to pamięć ciągłą, umożliwiłoby wydajną push_front, a nawet uniknęłoby dodatkowego pośrednictwa podczas dereferencji iteratorów.

Aby zminimalizować przesuwanie podczas wstawiania, zawarte wartości do przesunięcia zależą od punktu wstawienia. Jeśli wstawiasz w indeksie n przed size()/2, pozostały wartości przesunięcia do n. W przeciwnym razie przesuń w prawo wartości po n.

Czego mi brakowało, jest tak ważne, że deque to zbiór tablic wartości, a nie jeden wielki zestaw?

+0

zamortyzowanego kosztu, może być? Szybkie 'push_front' nie jest jedynym wymaganiem dla' deque' –

+1

Ile pamięci zostanie zarezerwowane? 1KB, 10KB, 1M, 1GB, 24GB? Cokolwiek zrobisz, ktoś będzie narzekał, że jest za dużo lub za mało ... –

+0

Afaik to sposób, w jaki Qt implementuje swoją QList – BeniBela

Odpowiedz

8

According to Wikipedia, to, co opisujesz, jest rzeczywiście jedną z możliwych implementacji, przynajmniej w ogóle.

Jednak standard C++ narzuca wymagania, które zasadniczo uniemożliwiają to jako implementację dla std::deque; [deque.modifiers] states:

Wstawienie na każdym końcu deque ... nie ma wpływu na ważność odniesień do elementów deque.

(dzięki @BenjaminLindley!)

+0

I STFW dla odpowiedzi, ale Wikipedia zwykle nie przychodzi mi na myśl o takich tematach (: – Gabriel

+4

23.3.3.4/1 i/4 mówi, że wstawienie lub usunięcie na końcu księgi nie unieważnia referencji. t być możliwe, jeśli deque działał w ten sposób (mówiłem już iteratory, ale to tylko odniesienia) –

+0

Więc implementacje, które opierają się na ciągłej pamięci z reallocs nie są zgodne ze standardem? Myślę, że inne implementacje mogłyby zapewnić kompatybilność C z 'c_array' funkcja, podobna do 'string :: c_str', która zapakuje wszystkie porcje w jedną dużą i zostanie unieważniona przez wstawki. – Gabriel

Powiązane problemy