2012-02-21 5 views
10

Durante la lectura de código que ver que:El intercambio de un vector con una copia de sí mismo

vector<TypeA>(typeAObj).swap(typeAObj); 

Mi pregunta es

¿Por qué se intercambian un vector con una copia de sí mismo?

+1

FWIW, [no está garantizado_ hacer nada] (http://stackoverflow.com/questions/7829018/can-we-rely-on-the-reduce-capacity-trick). –

+0

Tenga en cuenta que el vector no se intercambia con * en sí *, sino con una * copia * de sí mismo. –

+0

Escribí sobre la copia, Rawicki lo corrigió)) –

Respuesta

12

Ese es un patrón para contraer para ajustar en C++ 03, donde no existe tal operación en la interfaz de la clase de vector. Lo que hace el código es crear una copia (con suerte, el capacity del vector estará cerca del número de elementos disponibles) y luego lo intercambia con el vector original. Después de que la expresión se complete, el temporal (que ahora contiene los almacenamientos intermedios originales) se descarta y la memoria se libera.

considerar:

std::vector<int> large; 
large.reserve(10000000); // might be the result of multiple push_back/erase 
// large.capacity() >= 10000000 
large.push_back(1);  // Make more explicit that 'large' might not be empty 
std::vector<int>(large).swap(large); 
// large.capacity() is hopefully closer to 1 

En C++ 11 del tipo vector se ha modificado para proporcionar una operación de shrink_to_fit que toma en ese papel. Es importante tener en cuenta que ni el patrón antiguo ni shrink_to_fit son operaciones vinculantes, es decir, no hay garantía en el capacity del vector después de la operación que no sea capacity() >= size().

+0

Gracias David! Estaba seguro de que era un truco con un efecto secundario. –

+0

"* no hay garantía sobre la capacidad del vector después de la operación que no sea capacity()> = size() *" ... ¿Por qué es así? – Nawaz

+1

@Nawaz: simplemente es. El estándar C++ establece explícitamente que * shrink_to_fit * es una llamada no vinculante y establece que no existe tal garantía. En este patrón ocurre lo mismo, en ninguna parte del estándar se requiere que la copia no tenga la misma * capacidad * o incluso más que el objeto original. Los únicos requisitos en 'capacity()' es que debe ser al menos 'size()' por razones obvias. Aparte, el hecho de que este modismo funciona en muchas implementaciones para reducir la capacidad si es mucho mayor que el tamaño. –

8

Creo que es una forma de "encoger" el vector a un tamaño mínimo.

vector<TypeA>(typeAObj) crea una copia del vector cuyo tamaño reservado puede ser más pequeño que el original.

Así que intercambiar un vector con una copia nueva de sí mismo podría ser una forma de liberar alguna memoria no deseada.

Cuestiones relacionadas