2008-10-31 23 views

Respuesta

55

STL efectivo, por Scott Meyers, artículo 17: utilice el truco swap para recortar el exceso de capacidad.

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

Después de eso, persons es "escalada para ajustarse".

Esto se basa en el hecho de que el constructor de copias vector asigna solo la cantidad de memoria necesaria para los elementos que se copian.

+0

Sugerir una corrección a la gramática: 'shrunked', no 'shrinked' –

+0

Nice.¿Sabes quizás por qué no implementaron esto como método, ya que parece un caso de uso común para el contenedor? – bombardier

+1

Una vez que el vector ha asignado un búfer, es difícil eliminar [] el final de ese búfer. Y hacerlo simplemente garantiza que las inserciones futuras requerirán la asignación de un nuevo buffer y la copia de todo (invalidación de iteradores). –

8

Crea un vector nuevo, temporal, del existente, luego llama al método de intercambio en el existente, pasando el temporal en. Deja que el temporal (ahora con el antiguo, sobredimensionado, buffer) salga del alcance.

Hey presto, su vector tiene exactamente el tamaño correcto para su contenido.

Si esto suena como una gran cantidad de copia y asignación, tenga en cuenta que esto es lo que hace el vector cada vez que tiene realloc más allá de su límite reservado actual de todos modos.

[Editar] Sí, acabo de decir lo mismo que Sebastien en más palabras. Otro caso de stackoverflow raza-condición ;-)

+0

Bueno, te subí a Phil porque tu respuesta aún es útil, ¡incluso si no fuiste el primero en publicarla! :-) –

+0

Heh, gracias Onorio – philsquared

-2

Está buscando un equivalente de QVector::squeeze y me temo que no existe explícitamente en el STL. Busque la respuesta de Sébastien si es correcta para su implementación de STL.

16

Si está utilizando C++ 11, puede usar vec.shrink_to_fit(). En VS2010 al menos, eso hace el truco de intercambio para usted.

+0

No es equivalente al truco de intercambio. 'shrink_to_fit' es una solicitud no vinculante y no permite hacer nada. –

+2

Dije "en VS2010" pero sí, en otros compiladores puede que no lo haga. –

+5

@CatPlusPlus 'shrink_to_fit' hará con toda probabilidad el truco de intercambio o' realloc', pero con una pequeña optimización vectorial que aún no restablecerá 'capacity()' para que coincida con 'size()' porque no hay asignación de montón para reducir . Creo que esa es la razón por la que se especifica como "no vinculante". – Potatoswatter

2

El truco de intercambio es una manera eficaz de reducir la capacidad de un objeto, se intercambia el contenido de mi vector con un recién creado por la construcción de copia:

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

en cuenta que no hay ninguna garantía de que personas.capacidad(); después del truco de intercambio es igual a el tamaño: la capacidad del vector (personas) es la capacidad que la implementación de la biblioteca reserva a los vectores de tamaño persons.size().

C++ 11 introducido shrink_to_fit().

shrink_to_fit() así como el truco de intercambio no garantiza que el tamaño de la capacidad sea efectivamente reducido al tamaño del vector.

Anyway shrink_to_fit() puede invalidar sus iteradores (si ocurre una reasignación) o no puede hacerlo: depende de la implementación real de la biblioteca.

Tenga en cuenta que el truco de intercambio requiere person.size() copiar construcciones de Person y person.size() destructions. El shrink_to_fit() podría evitar toda esta copia y podría dejar los iteradores válidos. Podría. Pero de vez en cuando sucede que shrink_to_fit() se implementa en términos del truco de intercambio ...

+0

¿Podría indicar dónde se especifica que 'shrink_to_fit()' debe implementarse en términos de 'swap()'? –

+0

@TobySpeight gracias por la observación. Quizás mi inglés no sea lo suficientemente bueno. Quise decir que dado que _shrink_to_fit() _ puede implementarse en términos del truco de intercambio, a veces se implementa de esta manera. Déjame editar la respuesta. Si no tengo éxito, siéntase libre de editar la respuesta para mejorar su calidad. Su contribución sería bienvenida. Gracias – jimifiki