Biblioteca estándar de C++<iterator>

En la biblioteca estándar de C++<iterator>El archivo de cabecera proporciona un conjunto de herramientas para recorrer los elementos de los contenedores. Los iteradores son uno de los conceptos centrales de la Biblioteca de Plantillas Estándar (STL) de C++, que permiten a los programadores acceder a los elementos de un contenedor de manera uniforme, sin necesidad de preocuparse por los detalles específicos de implementación del contenedor.

Un iterador es un objeto que proporciona un método para recorrer los elementos de un contenedor. Un iterador puede considerarse como un puntero a los elementos de un contenedor, pero es más flexible y potente que un puntero. Los iteradores se pueden utilizar para acceder y modificar los elementos de un contenedor, y también se pueden usar junto con los algoritmos de STL.

Los iteradores se dividen principalmente en las siguientes categorías:

  1. Iterador de entrada (Input Iterator): solo puede realizar operaciones de lectura individuales y no puede realizar operaciones de escritura.
  2. Iterador de salida (Output Iterator): solo puede realizar operaciones de escritura individuales y no puede realizar operaciones de lectura.
  3. Iterador directo (Forward Iterator): puede realizar operaciones de lectura y escritura, y puede moverse hacia adelante.
  4. Iterador bidireccional (Bidirectional Iterator): además de poder realizar todas las operaciones de un iterador directo, también puede moverse hacia atrás.
  5. Iterador de acceso aleatorio (Random Access Iterator): además de poder realizar todas las operaciones de un iterador bidireccional, también puede realizar acceso aleatorio, por ejemplo, acceder a los elementos mediante un índice.

Funciones comunes (punto clave)

Función Propósito Ejemplo Descripción
std::advance(it, n) Mover el iterador n pasos advance(it, 2); Modifica el iterador original
std::distance(a, b) Calcula la distancia entre dos iteradores distance(v.begin(), v.end()); Devuelve el número de elementos
std::next(it, n) Devuelve un nuevo iterador n pasos hacia adelante auto it2 = next(it, 2); Recomendado, no modifica el valor original
std::prev(it, n) Devuelve un nuevo iterador n pasos hacia atrás auto it2 = prev(it, 1); Disponible desde C++11

Adaptadores de iteradores (muy importantes)

Los adaptadores de iteradores pueden cambiar el comportamiento de los iteradores, adaptándolos a diferentes escenarios de uso.

Adaptador Propósito Ejemplo
std::back_inserter Inserción al final (llama a push_back) back_inserter(vec)
std::front_inserter Inserción al principio (llama a push_front) front_inserter(list)
std::inserter Inserción en una posición específica inserter(vec, it)

Iteradores de flujo (la herramienta definitiva para simplificar IO)

Tipo Propósito Ejemplo
std::istream_iterator Lee datos del flujo de entrada istream_iterator<int>(cin)
std::ostream_iterator Escribe en el flujo de salida ostream_iterator<int>(cout, " ")

Sintaxis de los iteradores

La sintaxis de los iteradores suele ser la siguiente:

#include &lt;iterator&gt;

// 使用迭代器遍历容器
for (ContainerType::iterator it = container.begin(); it != container.end(); ++it) {
    // 访问元素 *it
}

Ejemplo

A continuación se muestra un ejemplo que utiliza el<iterator>archivo de cabecera y el recorrido con iteradoresstd::vector:

Ejemplo

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main() {
    // Crear un contenedor vector e inicializarlo
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // Usar iteradores para recorrer el vector
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // Usar la palabra clave auto para simplificar el tipo de iterador
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // Usar el bucle for basado en rangos de C++11
    for (int elem : vec) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Usar back_inserter para insertar automáticamente
    std::vector<int> v2;
    std::fill_n(std::back_inserter(v2), 3, 100);

    // Usar ostream_iterator para generar la salida
    std::copy(v2.begin(), v2.end(),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;

    return 0;
}

Resultado de salida:

1 2 3 4 5 
1 2 3 4 5 
1 2 3 4 5 
100 100 100 

Resumen

<iterator>El propósito principal se puede resumir en tres puntos:

  • Método de acceso unificado: diferentes contenedores usan la misma lógica de recorrido
  • Desacoplar contenedores y algoritmos: los algoritmos solo dependen de los iteradores
  • Mejorar la reutilización del código: el mismo código se puede aplicar a múltiples estructuras de datos

Para los principiantes, se recomienda dominar primero lo siguiente:

  • next / prev / distance
  • back_inserter
  • Métodos de recorrido con iteradores
Otras extensiones