C++ Coleções Intermediário
Iteradores
Os iteradores são objetos que permitem percorrer os elementos de um contêiner da biblioteca padrão (como std::vector, std::list, std::map) de forma genérica, sem precisar conhecer os detalhes internos de cada estrutura. Eles funcionam como uma abstração de ponteiros: você pode avançar (++), recuar (--), acessar o valor (*) e comparar posições.
Cada contêiner fornece os iteradores através dos métodos begin() e end(). O begin() aponta para o primeiro elemento, enquanto end() aponta para uma posição após o último elemento (um iterador "passado o fim"). O intervalo válido é sempre [begin, end) — inclui o início e exclui o fim. Esse padrão é usado em algoritmos como std::find, std::sort e em laços for baseados em intervalo.
Os iteradores são classificados em categorias que definem as operações suportadas: iteradores de entrada (leitura sequencial), de saída (escrita sequencial), forward (leitura/escrita múltipla passagem), bidirecionais (podem andar para trás, como os de std::list), de acesso aleatório (aritmética como it + n, como os de std::vector) e contíguos (C++20, memória contígua). Além disso, iteradores reversos (rbegin(), rend()) percorrem o contêiner do fim para o começo.
É crucial entender a invalidação de iteradores: operações que modificam o contêiner (inserir, remover, realocar) podem tornar iteradores existentes inválidos. Usar um iterador invalidado é comportamento indefinido. Por exemplo, em std::vector, qualquer operação que cause realocação invalida todos os iteradores; já em std::list, apenas os iteradores para elementos removidos são invalidados.
Pontos-chave
begin()aponta para o primeiro elemento;end()aponta para uma posição após o último.- Iteradores seguem categorias que determinam as operações permitidas (ex.:
++,--,+ n). - Modificar um contêiner pode invalidar iteradores; nunca use um iterador invalidado.
rbegin()erend()percorrem o contêiner na ordem reversa.- Prefira algoritmos da STL e
forbaseado em intervalo para evitar erros manuais.
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
int main() {
std::vector<int> v{10, 20, 30, 40, 50};
// Iteradores begin/end: percorre do início ao fim
std::cout << "Ordem normal: ";
for (auto it = v.begin(); it != v.end(); ++it)
std::cout << *it << ' ';
std::cout << '\n';
// Iteradores reversos: percorre do fim ao início
std::cout << "Ordem reversa: ";
for (auto rit = v.rbegin(); rit != v.rend(); ++rit)
std::cout << *rit << ' ';
std::cout << '\n';
// Algoritmo com iteradores: encontra o valor 30
auto it = std::find(v.begin(), v.end(), 30);
if (it != v.end())
std::cout << "Encontrado: " << *it << " na posicao " << (it - v.begin()) << '\n';
// Invalidação: inserir pode realocar e invalidar iteradores
v.push_back(60); // pode realocar; it pode ficar inválido
// Após modificar, obtemos novos iteradores se necessário
std::cout << "Tamanho apos push_back: " << v.size() << '\n';
return 0;
}