Un iterador es un puntero elaborado. Como un puntero, apunta a objetos del mismo tipo en la memoria en diferentes momentos. Todos los iteradores son desferencables, excepto el iterador de salida que se puede desferenciar solo para un conjunto de tipos. Derferencable significa que el valor apuntado por el puntero o el iterador se puede obtener utilizando el operador de indirección, *. Se puede agregar un entero a algunos iteradores de la misma manera, y para el mismo propósito, el entero se agregaría a un puntero.
Las preguntas para este artículo son: ¿Cuáles son estos iteradores?? ¿Cuál de estos iteradores se usa con el vector C ++?? ¿Cómo se usan estos iteradores con el vector C ++?? Este artículo responde a todas estas preguntas de manera simplificada. Al final de este artículo, cuando todas estas preguntas habrían sido respondidas, los iteradores vectoriales de C ++ serán intuitivos y naturales (para el lector).
Contenido del artículo
Resumen de los iteradores de C ++
Iterador de entrada
La idea del iterador de entrada es que un programa reciba el valor de entrada. A diferencia del iterador de salida, el iterador de entrada siempre es desferenciable. Para dos iteradores de entrada, A y B, "A == B" no implica "++ A == ++ B".
Iterador de salida
La idea del iterador de salida es que un programa libere el valor de salida. A diferencia del iterador de entrada, el iterador de salida no siempre se puede desferenciar. Se puede desferenciar solo para un conjunto de tipos.
Iterador delantero
El iterador delantero puede escanear el vector desde el principio hasta el final, uno por uno (incrementando). Tiene todos los requisitos del iterador de entrada, más requisitos adicionales. Puede sustituir a un iterador de entrada. Para dos iteradores delanteros, A y B, "A == B" implica "++ A == ++ B".
Iterador bidireccional
El iterador bidireccional puede escanear el vector desde el principio hasta el final, uno por uno. Desde el final hasta el principio, uno por uno (disminución). Tiene todos los requisitos del iterador delantero, además de requisitos adicionales. Puede sustituir a un iterador delantero. Para dos iteradores bidireccionales, A y B,
"A == B" implica "++ A == ++ B"
y
"-A == -b" implica "a == b".
Iterador de acceso aleatorio
El iterador de acceso aleatorio tiene todos los requisitos del iterador bidireccional, más requisitos adicionales. Puede sustituir a un iterador bidireccional. El iterador de acceso aleatorio tiene la ventaja de que si actualmente apunta al primer elemento y se requiere el cuarto elemento, se omitiría el segundo y tercer elemento y apuntaría al cuarto elemento. El omisión inversa hacia abajo es verdad.
Iterador inverso
Tenga en cuenta que C ++ no tiene un iterador inverso normal, ya que tiene un iterador delantero. Entonces, hay un adaptador llamado iterador inverso. Hay más buenas noticias: el iterador inverso cumple con todos los requisitos de un iterador bidireccional.
Iterador constante
Si se dice que un iterador es un constante, el elemento al que señala no se puede modificar.
Construcción y acceso vectorial
Los contenedores en C ++ son: Class Array, Deque, Forward_list, List, Vector, MAP, SET, Unordered_map y Unordered_set. El vector es un contenedor. Ciertas plantillas de funciones en la biblioteca estándar C ++ funcionan con iteradores directa o indirectamente. Los contenedores C ++, así como el vector, usan estas funciones. Estas funciones pueden estar disponibles para el programa C ++ con cualquiera de las siguientes directivas de inclusión:
#incluir
o
#incluir
La inclusión de cualquiera de los otros contenedores también pondrá a disposición estas plantillas de funciones. Una plantilla de función es para una función que puede funcionar con diferentes tipos de datos. El vector usa iteradores a través de estas plantillas de funciones. Algunas de las plantillas de funciones y su relación con el vector son las siguientes:
Construcción
Función de plantilla:
plantillaDatos automáticos de constexpr (C&C) -> DeclType (C.datos());
Auto significa que el tipo de retorno se determina en la evaluación de la función. c es el objeto de la clase C.
Un ejemplo de un objeto vectorial construido con este implícitamente es:
vectorVTR;
Aquí el objeto, C, está vacío.
Función de plantilla:
plantillaContexpr const e* datos (inicializer_list il) noexcept;
Aquí, E* es un iterador que apunta al primer elemento de la lista o contenedor. Su uso con el vector implícitamente sería con:
vectorvtr 'a', 'b', 'c', 'd', 'e';
vector:: const_iterator it = vtr.comenzar();
La función de plantilla es más aplicable a la instrucción inicial () (la segunda declaración).
Acceso
Función de plantilla:
plantillaTamaño automático de constexpr (const c & c) -> decltype (c.tamaño());
Esto devuelve el tamaño del contenedor. Ejemplo de vector:
vectorvtr 'a', 'b', 'c', 'd', 'e';
int n = vtr.tamaño();
cout << N << endl;
La salida es 5.
Función de plantilla:
plantilla[[Nodiscard]] Constexpr bool vacía (inicializer_list il) noexcept;
Devuelve verdadero si la lista está vacía o falsa de lo contrario. Ejemplo de vector:
vectorvtr 'a', 'b', 'c', 'd', 'e';
bool bl = vtr.vacío();
cout << bl << endl;
La salida es 0 para falso.
Acceso de rango
Hay otras funciones de plantilla, que usan iteradores que el vector utiliza para sus problemas de rango. Un rango es un conjunto consecutivo de elementos de contenedores.
Función de plantilla:
plantillaContexpr Auto Begin (C&C) -> DeclType (C.comenzar());
Esto devuelve un iterador que apunta al primer elemento en la lista. Auto aquí significa que el valor de retorno se determina en la evaluación. Ejemplo de vector:
vectorvtr 'a', 'b', 'c', 'd', 'e';
vector:: iterator it = vtr.comenzar();
cout << *it << '\n';
La salida es un. El iterador devuelto aquí es un iterador de acceso aleatorio. Un iterador de acceso aleatorio constante podría haberse devuelto; ver más tarde.
Plantilla de función:
plantillaConstexpr Auto End (const c & c) -> declype (c.fin());
Devuelve un iterador constante que apunta al último elemento de la lista. Código vectorial:
vectorvtr 'a', 'b', 'c', 'd', 'e';
vector:: const_iterator it = vtr.fin();
--él;
cout << *it << ";
--él;
cout << *it << endl;
La salida es "e d". Un iterador constante puede incrementarse o disminuir, pero el valor al que apunta no se puede cambiar. Un iterador de acceso aleatorio normal podría haberse devuelto; ver más tarde.
Plantilla de función:
plantillaconstexpr inverse_iterator rbegin (inicializador_list Illinois);
Devuelve el último valor en la lista. rbegin () señala el último elemento de la lista y no más allá del último elemento de la lista, como end () lo hace. Ejemplo de vector:
vectorvtr 'a', 'b', 'c', 'd', 'e';
vector:: reverse_iterator it = vtr.rbegin ();
cout << *it << ";
++él;
cout << *it << endl;
La salida es: E D. Con el iterador inverso, ++ tiene el efecto opuesto para el iterador bidireccional.
Plantilla de función:
plantillaconstexpr inverse_iterator Rend (inicializer_list Illinois);
Puntos justo antes del primer elemento de la lista. Ejemplo de vector:
vectorvtr 'a', 'b', 'c', 'd', 'e';
vector:: reverse_iterator it = vtr.desgarrar();
--él;
cout << *it << ";
--él;
cout << *it << endl;
La salida es una b. Con el iterador inverso, - tiene el efecto contrario para ++ del iterador bidireccional.
Hay otras funciones de plantilla bajo este encabezado; ver más tarde.
Insertar iteradores
Reverse_iterator es un adaptador iterador, no realmente un iterador. El iterador de inserción también es un adaptador iterador. Satisface todos los requisitos del iterador de salida, además de sus propios requisitos. Existe en tres formas en C ++: el back_inserter, el front_inserter y el inserter. Cada uno de estos tiene su propio constructor.
Back_interter:
Insertos en la parte posterior!
Prototipos importantes:
explícito back_insert_iterator (contenedor & x);
back_insert_iterator & operator = (Typename Container :: value_type && valor);
Ejemplo de vector:
El vector no tiene ninguna función de miembro de inserción que se inserta en la parte posterior. Sin embargo, la función miembro de push_back (t) se puede ver así.
front_interter
Insertos en la parte delantera!
Prototipos importantes:
explícito front_insert_iterator (contenedor & x);
front_insert_iterator & operator = (Typename Container :: value_type && value);
Ejemplo de vector:
El vector no tiene ninguna función de inserción miembro que se inserta en el frente. El vector no tiene la función miembro push_front (t).
La buena noticia es que el vector tiene funciones de miembros insertar que pueden insertar en cualquier lugar, al principio, dentro o el final del vector.
inserter
Este iterador se insertaría al principio, dentro o en el final del vector.
Prototipos importantes:
insert_iterator (Container & X, Typename Container :: Iterator I);
insert_iterator & operator = (contenedor typename :: value_type && value);
Ejemplo de vector:
vectorvtr 'a', 'b', 'c', 'd', 'e';
vector:: iterator it = vtr.comenzar();
it = it + 2;
VTR.insertar (it, 'c');
para (int i = 0; icout << vtr[i] << ", ";
cout <La salida es:
A, B, C, C, D, E,La expresión de inserción del vector es:
VTR.insertar (it, 'c');Inserta el elemento justo antes del puntero (it) apunta a.
Mover iterador
El movimiento_iterator también es un adaptador iterador. El siguiente programa es similar al ejemplo que se encuentra en la especificación C ++:
#incluir
#incluir
#incluir
usando el espacio de nombres STD;
int main ()
listachs 'a', 'b', 'c', 'd', 'e';
vectorVTR (make_move_iterator (CHS.begin ()), make_move_iterator (CHS.fin()));
cout << "Original list Content:" << endl;
para (auto it = chs.comenzar(); él != CHS.fin(); IT ++)
cout << *it << ", ";
cout << endl << endl;
cout << "Vector Content:" << endl;
para (int i = 0; icout << vtr[i] << ", ";
cout << endl;
regresar 0;La salida es:
Contenido de la lista original:
A B C D E,Contenido vectorial:
A B C D E,Este iterador convierte un valor de origen en un rValue antes de colocarlo en el destino.
Conclusión
Los principales iteradores en C ++ son iterador de entrada, iterador de salida, iterador delantero, iterador bidireccional y iterador de acceso aleatorio. La biblioteca estándar C ++ tiene algunas plantillas de función que usan estos iteradores. El vector usa estos iteradores a través de las plantillas de función. El vector tiene algunos nombres diferentes para algunos de estos iteradores. También hay adaptadores iteradores, que son: reverse_iterator, adaptador iterador y mude_iterator. También existen algunas variantes de los iteradores. Es suficiente incluir en un programa para tener todas estas características. Después de comprender el papel de estos iteradores, adaptadores y las plantillas de función que las usan, el uso de iteradores con vectores se vuelve intuitivo.