2010-03-24 14 views
22

Sé que esta es probablemente una pregunta tonta ... ¿Cuándo tendría que escribir mi propio iterador? ¿Es solo cuando diseño mi propia clase de contenedor? ¿Hay otras veces en las que me gustaría crear mi propio iterador?Cuándo escribir un iterador?

ejemplos serían apropiados.

-Jon

+7

Por lo que dicen las respuestas, ¡uno pensaría que todos estaban febrilmente escribiendo iteradores! Hablando personalmente, creo haberlo hecho quizás dos veces en mi carrera en C++. –

+3

Como se muestra en las respuestas, hay momentos en los que tiene sentido implementar un iterador personalizado, pero esos tiempos son raros. Si su clase de contenedor está construida sobre un contenedor STL, podría ser apropiado exponer los iteradores del contenedor subyacente en lugar de desplegar el suyo propio. –

+1

Principalmente creo que las personas mencionan los iteradores que están disponibles en alguna biblioteca. Por ejemplo, consulte http://www.boost.org/doc/libs/1_42_0/libs/iterator/doc/index.html#specialized-adaptors. No necesita implementarlos usted mismo;) – UncleBens

Respuesta

2

tiene que escribir propio iterador para su propia clase de contenedor o si necesita un comportamiento no estándar cuando iteración a través de los contenedores estándar.

3

Cuando se tiene una clase (muy probablemente un contenedor) y desea permitir a los usuarios que lo atraviesan convenientemente sin exponer los detalles de implementación, tendrá que crear un iterador.

Esto es aún más cierto cuando tiene una familia de clases (nuevamente, contenedores más probables) y desea proporcionar a sus usuarios una interfaz uniforme de iteración/recorrido para todas ellas, incluso si sus implementaciones son muy diferentes (es decir, lista vinculada versus una matriz).

7

Sí, hay otros momentos. Para algunos ejemplos:

  1. filter_iterator que solo devolvió un subconjunto filtrado de los elementos en un contenedor.
  2. Un iterador de selección que devolvió solo parte de un objeto.
  3. Un ostream_iterator que pone separadores antes o entre objetos, en lugar de después de ellos.
1

puedo ver dos casos en los que desea crear un nuevo iterador:

  • Por su propia clase de contenedor (como usted señala a sí mismo).
  • Un iterador con comportamiento personalizado para una clase contenedora existente. STL, por ejemplo, tiene backwards iterators. Tal vez le gustaría un every_3rd_iterator que solo devuelve cada tercer elemento? Tal iterador probablemente se implementaría como un adaptador alrededor de un iterador existente.
5

En cualquier momento que necesite para iterar sobre una secuencia de datos, y un iterador aún no está definido que se adapte a sus necesidades.

A menudo, se utiliza iteradores para recorrer los contenedores, pero eso está lejos de ser el único uso.

Un iterador también podría recorrer los resultados de una consulta de base de datos, o leer entrada de una secuencia (std::istream_iterator y std::istreambuf_iterator ya hacen esto, sin embargo), o tal vez necesite una orden o estrategia especial. Tal vez quiera iterar sobre "cada miembro de este vector, cuyo índice es divisible por cuatro", o "cada letra mayúscula en esta cadena", o cualquier otra cosa que se le ocurra.

+2

+1: algunos otros ejemplos que escapan a las otras respuestas: 'boost :: filesystem :: directory_iterator' no itera en un contenedor, sino en un directorio. 'pqxx :: result :: iterator' itera sobre los resultados de una consulta a un DB,' boost :: asio :: tcp :: resolver :: iterator' itera sobre tcp endpoints ... ninguno de ellos es exactamente un contenedor, pero ellos usan la expresión del iterador. –

+0

Coincidencias en una búsqueda de cadenas/expresiones regulares, etc. – UncleBens

1

Aparte de filtro y selección iteradores la única vez que he escrito iteradores en C++ es conseguir 3ª clases de contenedores partido a jugar bien con algoritmos de STL.Por ejemplo

  • Un iterador de acceso aleatorio para una secuencia de CORBA
  • Un insertador posterior para una secuencia de CORBA
  • Un iterador bidireccional de Dom XML, esto convierte un nodo DOM para un iterador que me permitió usar foreach y transformar en los nodos hermanos.

En general, no me gusta escribir iteradores porque son difíciles, hay muchas cosas de qué encargarse. Sin embargo, esta tarea es mucho más fácil con la biblioteca del iterador de impulso.

+1

De hecho acabo de descargar el impulso de ayer. Ahora si solo pudiera obtener la biblioteca por separado para construir ... – Jon

+0

Hola Jon, he tenido problemas para compilar bibliotecas de impulso antes también. Sin embargo, solo algunas de las bibliotecas deben ser compiladas. La mayoría son bibliotecas solo de encabezado y no necesitan ser compiladas simplemente incluidas.La biblioteca del iterador es uno de estos – iain

0

Es posible que también desee utilizarlos para iterar sobre secuencias numéricas, como números de Fibonacci o quizás números primos. Esto podría hacerse de otras maneras, probablemente más fácilmente, pero puede haber ocasiones en que el uso de un iterador para tales cosas tenga sentido.

2

La implementación de iteradores puede ser extremadamente útil y lo he hecho con bastante frecuencia. Un iterador es un concepto simple que todo el mundo sabe cómo usar. Los iteradores te permiten usar los algoritmos STL.

A menudo, se puede implementar iteradores para simplificar el uso de las API del sistema operativo de uso frecuente como Windows' FindNextFile

Cuando se escribe un file_iterator (ya existe en alza), puede hacerlo de repente:

file_iterator itBegin; // initialize appropriately 
file_iterator itEnd; 
std::vector<HANDLE> vecFiles(itBegin, itEnd); 

para obtener una lista de identificadores para todos los archivos coincidentes. Sin el iterador, las llamadas API necesarias habrían dificultado la lectura de su código.

Considere los iteradores como conceptos simples que le permiten escribir lo que realmente quiere decir y abstraer los detalles esenciales. Si tiene que implementar un algoritmo complejo que es difícil de entender por sí mismo, quiere reducir el desorden del código.

Si tiene una estructura bidimensional, p. std :: vector < std :: vector>, en otras palabras, una tabla, en la que se requiere que cada vector interno tenga la misma longitud, es posible que necesite iterar sobre cada n-ésimo elemento de los vectores internos. Si esto sucede con frecuencia suficiente, su código puede ser mucho más simple cuando implementa un iterador en lugar de propagar bucles forzados anidados en todo el código.

Cuestiones relacionadas