Iterators
Un iterador es un objeto que puede iterar sobre los elementos de un contenedor de la biblioteca estándar de C++ y proporcionar acceso a los elementos individuales. Todos los contenedores de la biblioteca estándar de C++ proporcionan los iteradores para que los algoritmos puedan tener acceso a sus elementos de manera estándar sin tener que preocuparse por el tipo de contenedor en el que están almacenados los elementos.
Puede usar iteradores explícitamente mediante funciones globales y miembro, como operadores y , como y para begin()end() avanzar o ++-- retroceder. También puede usar iteradores implícitamente con un bucle range-for o (para algunos tipos de iterador) el operador de subíndice [] .
En la biblioteca estándar de C++, el principio de una secuencia o un intervalo es el primer elemento. El final de una secuencia o un intervalo siempre se define como un elemento posterior al último elemento. Las funciones globales begin y end devuelven iteradores a un contenedor especificado. El típico bucle de iterador explícito de todos los elementos de un contenedor tiene este aspecto:
vector<int> vec{ 0,1,2,3,4 };
for (auto it = begin(vec); it != end(vec); it++)
{
// Access element using dereference operator
cout << *it << " ";
}
Se puede lograr lo mismo de forma más sencilla con un bucle de tipo range-for:
for (auto num : vec)
{
// no dereference operator
cout << num << " ";
}
Existen cinco categorías de iteradores. Ordenadas de menor a mayor potencia, las categorías son:
Salida. Un iterador de salida puede iterar hacia delante en una secuencia mediante el operador y puede escribir un elemento solo una
++vez, mediante el operador*.Entrada. Un iterador de entrada puede iterar hacia delante en una secuencia mediante el operador y puede leer un elemento varias veces
++mediante el operador*. Puede comparar los iteradores de entrada mediante los==operadores!=y . Después de incrementar cualquier copia de un iterador de entrada, ninguna de las otras copias se puede comparar, desreferenciar o incrementar posteriormente de forma segura.Reenviar. Un iterador hacia delante puede iterar hacia delante en una secuencia mediante el operador ++ y puede leer cualquier elemento o escribir elementos no const varias veces mediante el operador
*. Puede acceder a los miembros del elemento mediante el operador y comparar->los iteradores hacia delante mediante los operadores y==!=. También puede realizar varias copias de un iterador hacia delante, cada una de las cuales puede desreferenciarse e incrementarse de forma independiente. Un iterador hacia delante que se inicializa sin referencia a ningún contenedor se denomina iterador hacia delante nulo. Los iteradores hacia delante nulos siempre se comparan igual.Bidireccional. Un iterador bidireccional puede tomar el lugar de un iterador hacia delante. Sin embargo, también puede disminuir un iterador bidireccional, como en
--XX--, o(V = *X--). Puede acceder a los miembros de elemento y comparar los iteradores bidireccionales de la misma manera que los iteradores hacia delante.Acceso aleatorio. Un iterador de acceso aleatorio puede tomar el lugar de un iterador bidireccional. Con un iterador de acceso aleatorio, puede usar el operador de subíndice para tener acceso a
[]los elementos. Puede usar los operadores , y para avanzar o retroceder un número especificado de elementos y calcular la distancia+-entre+=-=iteradores. Puede comparar iteradores bidireccionales mediante==, , , , y!=<><=>=.
Todos los iteradores pueden asignarse o copiarse. Se supone que son objetos ligeros y a menudo se pasan y devuelven por valor, no por referencia. Tenga en cuenta que ninguna de las operaciones descritas anteriormente puede iniciar una excepción cuando se realizan en un iterador válido.
La jerarquía de las categorías de iterador se puede resumir mostrando tres secuencias. Para el acceso de solo escritura a una secuencia, puede usar cualquiera de los siguientes:
iterador de salida
- > iterador hacia delante
- > iterador bidireccional
- > Iterador de acceso aleatorio
La flecha derecha significa "se puede reemplazar por". Cualquier algoritmo que llame a un iterador de salida debe funcionar bien con un iterador hacia delante, por ejemplo, pero no al revés.
Para el acceso de solo lectura a una secuencia, puede usar cualquiera de los siguientes:
iterador de entrada
- > iterador hacia delante
- > iterador bidireccional
- > Iterador de acceso aleatorio
En este caso, el iterador de entrada es la categoría más débil.
Por último, para el acceso de lectura y escritura a una secuencia, puede usar cualquiera de los siguientes:
iterador hacia delante
- > iterador bidireccional
- > Iterador de acceso aleatorio
Un puntero de objeto siempre puede servir como iterador de acceso aleatorio, por lo que puede usarse como cualquier categoría de iterador si admite el correspondiente acceso de lectura y escritura a la secuencia que designa.
Un iterador Iterator distinto de un puntero de objeto también debe definir los tipos de miembro que requiere la especialización iterator_traits<Iterator>. Estos requisitos se pueden cumplir derivando del IteratorIteratorde clase base pública .
Es importante comprender las promesas y limitaciones de cada categoría de iterador para ver cómo usan los iteradores los contenedores y algoritmos en la biblioteca estándar de C++.
Nota
Puede evitar el uso de iteradores de forma explícita mediante bucles de tipo range-for. Para obtener más información, vea Range-based for statement.
Microsoft C++ ahora ofrece iteradores comprobados e iteradores de depuración para asegurarse de que no sobrescribe los límites del contenedor. Para obtener más información, vea Iteradores comprobados y Compatibilidad de los iteradores de depuración.
Vea también
Referencia de la biblioteca estándar de C++
Seguridad para subprocesos en la biblioteca estándar de C++