Última actualización:2026-10-12
STL invalidación de iteradores¶
https://stackoverflow.com/questions/6438086/iterator-invalidation-rules-for-c-containers
Inserción Contenedores secuenciales
- vector: los iteradores y referencias anteriores al punto de inserción no se ven afectados, salvo que el tamaño del nuevo contenedor supere la capacidad anterior (en cuyo caso todos los iteradores y referencias quedarán invalidados) [23.3.6.5/1]
- deque: todos los iteradores y referencias quedarán invalidados, salvo que los elementos insertados estén en los extremos del deque (delante o detrás) (en cuyo caso todos los iteradores quedarán invalidados, pero las referencias a los elementos no se verán afectadas) [23.3.3.4/1]
- list: ningún iterador ni referencia quedan invalidados [23.3.5.4/1]
- forward_list: ningún iterador ni referencia quedan invalidados (aplica a insert_after) [23.3.4.5/1]
- array: (no aplica)
Contenedores asociativos
- [multi]{set,map}: ningún iterador ni referencia quedan invalidados [23.2.4/9]
Contenedores asociativos no ordenados
- unordered_[multi]{set,map}: cuando se produce un rehash, todos los iteradores quedarán invalidados, pero las referencias no se ven afectadas [23.2.⅝]. Si la inserción no hace que el tamaño del contenedor supere z * B, no se producirá rehash, donde z es el factor de carga máximo y B el número actual de cubos [23.2.5/14]
Adaptadores de contenedor
- stack: hereda del contenedor subyacente
- queue: hereda del contenedor subyacente
- priority_queue: hereda del contenedor subyacente
Borrado Contenedores secuenciales
- vector: todos los iteradores y referencias desde el punto de borrado en adelante quedarán invalidados [23.3.6.5/3]
- deque: borrar el último elemento invalida únicamente los iteradores y referencias al elemento borrado y al iterador past-the-end; borrar el primer elemento invalida únicamente los iteradores y referencias al elemento borrado; borrar cualquier otro elemento invalida todos los iteradores y referencias (incluido el iterador past-the-end) [23.3.3.4/4]
- list: solo quedan invalidados los iteradores y referencias al elemento borrado [23.3.5.4/3]
- forward_list: solo quedan invalidados los iteradores y referencias al elemento borrado (aplica a erase_after) [23.3.4.5/1]
- array: (no aplica)
Contenedores asociativos
- [multi]{set,map}: solo quedan invalidados los iteradores y referencias al elemento borrado [23.2.4/9]
Contenedores asociativos no ordenados
- unordered_[multi]{set,map}: solo quedan invalidados los iteradores y referencias al elemento borrado [23.2.5/13]
Adaptadores de contenedor
- stack: hereda del contenedor subyacente
- queue: hereda del contenedor subyacente
- priority_queue: hereda del contenedor subyacente
Redimensionado - vector: igual que en las operaciones de inserción/borrado [23.3.6.5/12] - deque: igual que en las operaciones de inserción/borrado [23.3.3.3/3] - list: igual que en las operaciones de inserción/borrado [23.3.5.3/1] - forward_list: igual que en las operaciones de inserción/borrado [23.3.4.5/25] - array: (no aplica)
Nota 1 Salvo que se estipule explícitamente lo contrario (ya sea de forma explícita o mediante funciones definidas en términos de otras funciones), llamar a una función miembro de un contenedor o pasar un contenedor como argumento a una función de la biblioteca no invalidará los iteradores a los objetos de ese contenedor ni alterará sus valores. [23.2.1/11]
Nota 2 Ninguna función swap() invalida las referencias, punteros o iteradores que apuntan a los elementos de los contenedores intercambiados. [Nota: el iterador end() no apunta a ningún elemento, por lo que sí puede quedar invalidado. — fin de la nota] [23.2.1/10]
Nota 3 Salvo la advertencia anterior sobre swap(), no está claro si el iterador "end" está sujeto a cada una de las reglas anteriores por contenedor; en cualquier caso, deberías asumir que sí lo está.
Nota 4 vector y todos los contenedores asociativos no ordenados admiten reserve(n), que garantiza que no habrá un redimensionado automático al menos hasta que el tamaño del contenedor crezca hasta n. Con los contenedores asociativos no ordenados conviene ser prudente, porque futuras propuestas permitirán especificar un factor de carga mínimo, lo que hará posible que, tras suficientes borrados que reduzcan el tamaño del contenedor por debajo del mínimo, se produzca un rehash en una inserción; por tanto, tras un borrado, esa garantía debe considerarse potencialmente inválida.
https://en.cppreference.com/w/cpp/container#Iterator_invalidation
for (auto it = c.begin(); it != c.end(); /*inc in loop*/)
{
if (it->shouldErase())
{
it = c.erase(it);
continue;
}
...
++it;
}
auto is_dead = [](auto const& e) { return !(e->is_alive()); };
std::erase_if(m_entities, is_dead);
std::erase_if(m_entity_map, is_dead);
erase_if or remove_if
https://stackoverflow.com/questions/39019806/using-erase-remove-if-idiom
https://kera.name/articles/2011/06/iterator-invalidation-rules-c0x/
Temas relacionados¶
- Análisis del código fuente de STL array | C++那些事
- Análisis profundo de STL string | C++那些事
- STL string preguntas de entrevista explicadas | C++那些事
- Análisis del código fuente de STL deque | C++那些事
- STL optimización de clase base vacía EBO | C++那些事
- STL implementación de una tabla hash escrita a mano | C++那些事
- STL hashtable tabla hash | C++那些事
- Análisis del código fuente de los iteradores STL | C++那些事
- Análisis del código fuente de STL list | C++那些事
- STL map y multimap | C++那些事