Ponieważ to pytanie przyciąga tyle głosów, a rodzaj pytania staje się często zadawanym pytaniem, lepiej byłoby napisać osobną odpowiedź, aby wspomnieć o jednej znaczącej różnicy między C ++ 03 i C ++ 11 dotyczącej wpływu std::vector
operacji wstawiania na ważność iteratorów i odniesień do reserve()
icapacity()
, których najbardziej pozytywna odpowiedź nie została zauważona.
C ++ 03:
Realokacja unieważnia wszystkie odwołania, wskaźniki i iteratory odnoszące się do elementów w sekwencji. Zagwarantowane jest, że podczas wstawiania, które następuje po wywołaniu zarezerwowania (), nie nastąpi żadna realokacja, aż do momentu, gdy wstawienie zwiększy rozmiar wektora niż rozmiar określony w ostatnim wywołaniu zarezerwowanym () .
C ++ 11:
Realokacja unieważnia wszystkie odwołania, wskaźniki i iteratory odnoszące się do elementów w sekwencji. Zagwarantowane jest, że podczas wstawiania, które następuje po wywołaniu funkcji zarezerwować (), nie nastąpi żadna realokacja, dopóki czas wstawienia nie zwiększy wielkości wektora niż wartość pojemność () .
Tak więc w C ++ 03 nie jest to „ unless the new container size is greater than the previous capacity (in which case all iterators and references are invalidated)
”, jak wspomniano w innej odpowiedzi, zamiast tego powinno być „ greater than the size specified in the most recent call to reserve()
”. Jest to jedna rzecz, którą C ++ 03 różni się od C ++ 11. W C ++ 03, gdy jeden raz insert()
spowoduje, że rozmiar wektora osiągnie wartość określoną w poprzednim reserve()
wywołaniu (która może być mniejsza niż bieżąca, capacity()
ponieważ reserve()
wynik może być większy capacity()
niż wymagany), każde następne insert()
może spowodować realokację i unieważnienie wszystkie iteratory i referencje. W C ++ 11 tak się nie stanie i zawsze możesz mieć capacity()
pewność, że będziesz mieć pewność, że następna realokacja nie nastąpi przed przekroczeniem rozmiaru capacity()
.
Podsumowując, jeśli pracujesz z wektorem C ++ 03 i chcesz mieć pewność, że przeniesienie nie nastąpi podczas wykonywania wstawiania, jest to wartość argumentu, który wcześniej przekazałeś reserve()
, że powinieneś sprawdzić rozmiar, a nie wartość zwrotną połączenia do capacity()
, w przeciwnym razie możesz być zaskoczony „ przedwczesną ” realokacją.