Lección 13 · 13 de 20
Iteradores · C++
Recorra contenedores de C++ con iteradores: begin, end, rbegin, next, distance y erase en un std::list, con una ruta y una lista de reproducción.

Un iterador señala un elemento de un contenedor: *it lo lee, ++it pasa al siguiente y it != route.end() comprueba si se ha llegado al final. Ojo: end() no es el último elemento, sino la posición que viene después. Los iteradores son lo que usa por dentro el for de rango y lo que reciben todos los algoritmos.
std::next(it) devuelve el iterador siguiente sin mover it; aquí sirve para saber si quedan ciudades y poner -> solo entre ellas. Con `rbegin()` y `rend()` se recorre al revés con el mismo código: el viaje de vuelta.
Los iteradores de std::vector son de acceso aleatorio: admiten aritmética, como route.begin() + 2. std::distance cuenta los pasos entre dos iteradores y stop->size() llama a un método del elemento señalado, igual que con un puntero.
En un `std::list` (una lista doblemente enlazada) insertar y borrar en medio es barato, pero borrar invalida el iterador del elemento borrado. Por eso erase(it) devuelve el siguiente y el bucle solo avanza con ++it cuando no borra. insert coloca «Jingle» delante de la posición indicada, la segunda. `cbegin()` y `cend()` dan iteradores const, que solo dejan leer.
Código · main.cpp
#include <iostream>#include <iterator>#include <list>#include <string>#include <vector>int main() { // An iterator points to an element: *it reads it and ++it moves to the next. std::vector<std::string> route = {"Madrid", "Zaragoza", "Lleida", "Barcelona"}; for (auto it = route.begin(); it != route.end(); ++it) std::cout << *it << (std::next(it) != route.end() ? " -> " : "\n"); // Reverse iterators walk backwards: the trip home. for (auto it = route.rbegin(); it != route.rend(); ++it) std::cout << *it << (std::next(it) != route.rend() ? " -> " : "\n"); // Vector iterators allow arithmetic; distance counts the steps. auto stop = route.begin() + 2; std::cout << "Third stop: " << *stop << ", " << std::distance(route.begin(), stop) << " steps from the start, " << stop->size() << " letters\n"; // In a list, erasing and inserting through an iterator is cheap. std::list<std::string> playlist = {"Intro", "Ad", "Song A", "Ad", "Song B"}; for (auto it = playlist.begin(); it != playlist.end();) { if (*it == "Ad") it = playlist.erase(it); // erase returns the next one else ++it; } playlist.insert(std::next(playlist.begin()), "Jingle"); // before the 2nd track for (auto it = playlist.cbegin(); it != playlist.cend(); ++it) // const: read only std::cout << "[" << *it << "]"; std::cout << "\n";}Salida · c++ -std=c++17 main.cpp -o main && ./main
Madrid -> Zaragoza -> Lleida -> Barcelona Barcelona -> Lleida -> Zaragoza -> Madrid Third stop: Lleida, 2 steps from the start, 6 letters [Intro][Jingle][Song A][Song B]
Para recordar
*itlee el elemento,++itavanza yend()está después del último.rbegin()yrend()recorren al revés.std::next,std::distancey la aritméticabegin() + nmueven y miden.erase(it)devuelve el iterador siguiente: úselo al borrar dentro de un bucle.cbegin()ycend()dan iteradores de solo lectura.
Ejercicio
Use std::find para obtener un iterador a «Song A» en la lista de reproducción e inserte «Encore» justo después (pista: std::next). Escriba la lista final.