
daniel sloof
He estado leyendo sobre contenedores STL en mi libro sobre C++, específicamente la sección sobre STL y sus contenedores. Ahora entiendo que todos y cada uno de ellos tienen sus propias propiedades específicas, y estoy cerca de memorizarlos todos… Pero lo que aún no entiendo es en qué escenario se usa cada uno de ellos.
¿Cuál es la explicación? Se prefiere mucho el código de ejemplo.

zdan
esta hoja de trucos proporciona un resumen bastante bueno de los diferentes contenedores.
Consulte el diagrama de flujo en la parte inferior como una guía para usar en diferentes escenarios de uso:

Creado por david moore y con licencia CC BY-SA 3.0
Aquí hay un diagrama de flujo inspirado en la versión de David Moore (ver arriba) que creé, que está actualizado (en su mayoría) con el nuevo estándar (C++ 11). Esta es solo mi opinión personal, no es indiscutible, pero pensé que podría ser valiosa para esta discusión:


david thornley
Respuesta simple: usar std::vector
para todo a menos que tenga una razón real para hacer lo contrario.
Cuando encuentre un caso en el que esté pensando: “Caramba, std::vector
no funciona bien aquí debido a X”, vaya sobre la base de X.
Mira Eficaz STL de Scott Meyers. Es bueno para explicar cómo usar el STL.
Si desea almacenar un número determinado/indeterminado de objetos y nunca va a eliminar ninguno, entonces lo que desea es un vector. Es el reemplazo predeterminado de una matriz C y funciona como tal, pero no se desborda. También puede establecer su tamaño de antemano con reserve().
Si desea almacenar una cantidad indeterminada de objetos, pero los agregará y los eliminará, entonces probablemente desee una lista… porque puede eliminar un elemento sin mover los siguientes elementos, a diferencia del vector. Sin embargo, requiere más memoria que un vector y no puede acceder secuencialmente a un elemento.
Si desea tomar un montón de elementos y encontrar solo los valores únicos de esos elementos, leerlos todos en un conjunto lo hará, y también los clasificará por usted.
Si tiene muchos pares clave-valor y desea ordenarlos por clave, entonces un mapa es útil… pero solo tendrá un valor por clave. Si necesita más de un valor por clave, puede tener un vector/lista como su valor en el mapa o usar un mapa múltiple.
No está en la STL, pero sí en la actualización TR1 de la STL: si tiene muchos pares clave-valor que va a buscar por clave y no le importa su orden, puede quiere usar un hash, que es tr1::unordered_map. Lo he usado con Visual C++ 7.1, donde se llamaba stdext::hash_map. Tiene una búsqueda de O(1) en lugar de una búsqueda de O(log n) para el mapa.

Ebrahim
Rediseñé el diagrama de flujo para que tuviera 3 propiedades:
- Creo que los contenedores STL se dividen en 2 clases principales. Los contenedores básicos y aquellos aprovechan los contenedores básicos para implementar una política.
- Al principio, el diagrama de flujo debe dividir el proceso de decisión en las situaciones principales sobre las que debemos decidir y luego elaborar cada caso.
- Algunos contenedores ampliados tienen la posibilidad de elegir diferentes contenedores básicos como su contenedor interior. El diagrama de flujo debe considerar las situaciones en las que se puede utilizar cada uno de los contenedores básicos.
El diagrama de flujo: 
Más información proporcionada en este enlace.

Pedro Mortensen
Un punto importante que solo se mencionó brevemente hasta ahora es que si necesita memoria contigua (como la que proporciona una matriz C), entonces solo puede usar vector
, array
o string
.
Utilizar array
si el tamaño se conoce en tiempo de compilación.
Utilizar string
si solo necesita trabajar con tipos de caracteres y necesita una cadena, no solo un contenedor de propósito general.
Utilizar vector
en todos los demás casos (vector
debería ser la opción predeterminada de contenedor en la mayoría de los casos de todos modos).
Con los tres de estos se puede utilizar el data()
función miembro para obtener un puntero al primer elemento del contenedor.

Ofertas
Todo depende de lo que quieras almacenar y lo que quieras hacer con el contenedor. Aquí hay algunos ejemplos (muy no exhaustivos) de las clases de contenedor que tiendo a usar más:
vector
: diseño compacto con poca o ninguna sobrecarga de memoria por objeto contenido. Eficiente para iterar. Agregar, insertar y borrar puede ser costoso, especialmente para objetos complejos. Barato para encontrar un objeto contenido por índice, por ejemplo, myVector[10]. Úselo donde hubiera usado una matriz en C. Bueno, donde tiene muchos objetos simples (por ejemplo, int). No olvides usar reserve()
antes de agregar muchos objetos al contenedor.
list
: pequeña sobrecarga de memoria por objeto contenido. Eficiente para iterar. Agregar, insertar y borrar son baratos. Use donde hubiera usado una lista enlazada en C.
set
(y multiset
): sobrecarga de memoria significativa por objeto contenido. Úselo donde necesite averiguar rápidamente si ese contenedor contiene un objeto determinado, o combine contenedores de manera eficiente.
map
(y multimap
): sobrecarga de memoria significativa por objeto contenido. Úselo donde desee almacenar pares clave-valor y busque valores por clave rápidamente.
El diagrama de flujo en el hoja de trucos sugerido por zdan proporciona una guía más exhaustiva.
¿Te refieres a mapa, vectot, conjunto, etc.?
– Thomas Tempelman
23 de enero de 2009 a las 0:35
Incluso mirando este diagrama, no puedo decir cuál sería el mejor para usar en mi pregunta stackoverflow.com/questions/9329011/…
– sergiol
24 de febrero de 2012 a las 19:32
he creado un Versión editable de la hoja de referencia del contenedor C++ de Mikael. Esta es la hoja de trucos de @MikaelPersson. Lamentablemente, no puedo comentar sobre su respuesta porque aún no tengo 50 reputación.
–Parker Shamblin
14 de agosto de 2020 a las 19:53