Da trilha de C++ Este conceito ainda não saiu como card do dia. ir para o card de hoje

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() e rend() percorrem o contêiner na ordem reversa.
  • Prefira algoritmos da STL e for baseado em intervalo para evitar erros manuais.
iteradores.cpp
#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;
}

Exercícios

  1. 1
    Fácil

    Percorrendo um vetor com iteradores

    Escreva um programa que crie um std::vector<int> com os valores {2, 4, 6, 8, 10} e use iteradores (begin() e end()) para imprimir cada elemento separado por espaço, em uma única linha.

    Resolver
  2. 2
    Médio

    Iteradores reversos e algoritmo

    Crie um std::list<std::string> com as frutas {"maçã", "banana", "laranja", "uva"}. Use iteradores reversos para imprimir os elementos na ordem inversa, um por linha. Em seguida, use std::find com iteradores normais para verificar se "laranja" está na lista e imprima "encontrado" ou "nao encontrado".

    Resolver
  3. 3
    Desafio

    Invalidação de iteradores e remoção segura

    Escreva uma função que receba um std::vector<int> e remova todos os números pares usando iteradores. Como a remoção pode invalidar iteradores, utilize a técnica de erase-remove idiom com std::remove_if e erase. Depois, imprima o vetor resultante. Em seguida, mostre um exemplo de invalidação: crie um iterador para o primeiro elemento, faça push_back e explique por que o iterador pode ter sido invalidado (comente no código).

    Resolver

Continue estudando