2008-10-31 32 views

Odpowiedz

55

Efektywny STL, autor: Scott Meyers, pozycja 17: Użyj sztuczki swap, aby przyciąć nadmiarową pojemność.

vector<Person>(persons).swap(persons); 

Po tym, persons jest "skurczony, aby zmieścić".

Wynika to z faktu, że konstruktor kopiowania vector przydziela tylko tyle, ile potrzeba dla kopiowanych elementów.

+0

Zaproponuj poprawkę do gramatyki: "skurczona", a nie "pomniejszona" –

+0

Ładna.Czy może wiesz, dlaczego nie zaimplementowali tego jako metody, ponieważ wygląda to na typowy przypadek użycia kontenera? – bombardier

+1

Po przydzieleniu przez wektor bufora trudno jest usunąć [] koniec tego bufora. Takie działanie gwarantuje po prostu, że przyszłe wstawienia będą wymagały przydzielenia nowego bufora i skopiowania do niego całego pliku (unieważnienie iteratorów). –

8

Utwórz nowy, tymczasowy wektor z istniejącego, a następnie wywołaj metodę wymiany na istniejącym, przekazując tymczasowy. Pozwól, aby tymczasowy (teraz ze starym, ponadwymiarowym, bufor) wyszedł poza zasięg.

Hej presto, twój wektor ma dokładnie odpowiedni rozmiar do zawartości.

Jeśli brzmi to jak dużo kopiowania i alokacji - pamiętaj, że tak właśnie robi wektor za każdym razem, gdy musi ponownie dokonać przydziału według dotychczasowego zarezerwowanego limitu.

[Edytuj] Tak, właśnie powiedziałem to samo, co Sebastien, innymi słowy. Kolejny przypadek stackoverflow race-condition ;-)

+0

Cóż, przegłosowałem ciebie, ponieważ twoja odpowiedź jest nadal pomocna, nawet jeśli nie byłeś pierwszym, który to opublikował! :-) –

+0

Heh, dzięki Onorio – philsquared

-2

Szukasz odpowiednika QVector::squeeze i obawiam się, że nie istnieje w sposób wyraźny w STL. Przejdź do odpowiedzi Sébastiena, jeśli jest ona poprawna dla twojej implementacji STL.

16

Jeśli używasz C++ 11, możesz użyć vec.shrink_to_fit(). W VS2010 przynajmniej to robi sztuczkę z zamianą dla ciebie.

+0

To nie jest odpowiednik sztuczki wymiany. 'shrink_to_fit' jest niewiążącym żądaniem i wolno mu nic nie robić. –

+2

Powiedziałem "w VS2010", ale tak, na innych kompilatorach może tego nie robić. –

+5

@CatPlusPlus 'shrink_to_fit' z dużym prawdopodobieństwem wykona operację zamiany lub' realloc', ale z małą optymalizacją wektorów, która nadal nie spowoduje zresetowania 'capacity()', aby dopasować 'size()', ponieważ nie ma przydziału sterty aby zmniejszyć . Myślę, że to jest powód, dla którego jest określony jako "niewiążący". – Potatoswatter

2

Swap Sztuką jest skutecznym sposobem na zmniejszenie pojemności obiektu, to zamienia treść mojego wektora z nowo utworzonego jeden po budowie kopię:

vector<Person>(persons).swap(persons); 

Zauważ, że nie ma gwarancji, że persons.capacity(); po podmienianiu jest równa wielkość: pojemność wektora (osób) jest pojemnością, którą implementacja biblioteki rezerwuje wektorom wielkości persons.size().

C++ 11 wprowadzono shrink_to_fit().

shrink_to_fit() jak również sztuczka typu swap nie gwarantuje, że wielkość pojemności jest efektywnie zmniejszona do wielkości wektora.

W każdym razie shrink_to_fit() może unieważnić twoje iteratory (jeśli nastąpi realokacja) lub nie może: to zależy od rzeczywistej implementacji biblioteki.

Należy pamiętać, że sztuczka swap wymaga persons.size() kopiowania konstrukcji Person i person.size() destructions. Funkcja shrink_to_fit() może ominąć to kopiowanie i może pozostawić twoje iteratory ważne. Mógłby. Ale od czasu do czasu zdarza się, że shrink_to_fit() jest zaimplementowany w warunkach wymiany ...

+0

Czy mógłbyś wskazać, gdzie jest określone, że 'shrink_to_fit()' musi być zaimplementowane pod względem 'swap()'? –

+0

@ TobySpeight dzięki za uwagę. Może mój angielski nie jest wystarczająco dobry. Miałem na myśli to, że ponieważ _shrink_to_fit() _ może być zaimplementowany w kategoriach wymiany, to czasami jest implementowany w ten sposób. Pozwól mi edytować odpowiedź. Jeśli mi się nie uda, możesz edytować odpowiedź, aby poprawić jej jakość. Twój wkład byłby mile widziany. Dzięki – jimifiki

Powiązane problemy