Historia de la cuestión:
Apareciendo en STL en C++98, los iteradores permitieron abstraerse de estructuras de datos específicas, proporcionando un acceso unificado a los elementos del contenedor. Con la adopción de C++20, se agregó el estándar de rangos, lo que aumentó aún más la expresividad y seguridad al trabajar con contenedores.
Problema:
El uso incorrecto de los iteradores puede llevar a errores en tiempo de ejecución: fuera de los límites del contenedor, invalidación después de cambios. El soporte para diferentes tipos de iteradores puede llevar a comportamientos inesperados si se confunden entre sí. Trabajar "manualmente" con begin()/end() requiere disciplina.
Solución:
Usar el tipo de iterador correspondiente a las capacidades del contenedor (por ejemplo, acceso aleatorio solo en vector/deque/array). No almacenar iteradores inválidos. Para tareas modernas, usar más a menudo rangos y algoritmos estandarizados.
Ejemplo de código:
#include <vector> #include <algorithm> #include <iostream> #include <ranges> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // Iteración a través del iterador for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } // Iteración a través del rango for (int x : vec | std::ranges::views::filter([](int v){return v % 2 == 0;})) { std::cout << x << " "; } return 0; }
Características clave:
¿Qué sucederá con el iterador std::vector después de la llamada a push_back?
Si después de push_back, el tamaño del contenedor aumenta (rebalanceo), todos los iteradores y referencias antiguos se vuelven inválidos. Después de push_back sin cambiar la capacidad, los iteradores se mantienen. Es más seguro no almacenar iteradores entre modificaciones.
¿Cuál es la diferencia entre un iterador random-access y uno bidirectional?
Random-access soporta aritmética (it + n) y acceso por índice (it[n]), mientras que bidirectional solo soporta ++ y --. No todos los contenedores STL soportan random-access.
¿Pueden los algoritmos estándar de STL trabajar con punteros comunes?
Sí, porque un puntero en C++ cumple completamente con los requisitos de un iterador de acceso aleatorio.
En un bucle sobre std::list, el desarrollador modifica directamente el contenedor usando el método erase, sin actualizar el iterador, lo que provoca un error en tiempo de ejecución.
Ventajas:
Desventajas:
Antes de modificar el contenedor, siempre se guarda el siguiente iterador. Se utilizan algoritmos estándar como erase-remove idiom para vectores o list::remove_if para listas.
Ventajas:
Desventajas: