2010-03-25 15 views

Respuesta

6

Todos los contenedores estándar proporcionan el concepto de iterador. Un iterador sabe cómo encontrar el siguiente elemento en el contenedor, especialmente cuando la estructura subyacente no es similar a una matriz. Los contenedores no proporcionan el estilo de matriz operator[], por lo que adquirir el hábito de usar iteradores hará que el código tenga una apariencia más uniforme, independientemente del contenedor que elija.

3

Puede abstraer la implementación de la colección.

14

Supongo que está hablando de cuando se usa un vector, ¿verdad?

La principal ventaja es que el código de iterador funciona para todos los contenedores stl, mientras que el operador de indexación de matrices [] solo está disponible para vectores y deques. Esto significa que puede cambiar el contenedor subyacente si lo necesita sin tener que volver a codificar cada ciclo. También significa que puede poner su código de iteración en una plantilla y funcionará para cualquier contenedor, no solo para deques y vectores (y matrices, por supuesto).

+0

Además, puede escribir un iterador personalizado que pueda cargar datos de una base de datos o generar datos utilizando algún algoritmo. Es extremadamente flexible. La desventaja es que los iteradores pueden ocultar operaciones arbitrariamente complejas (por ejemplo, acceder a una base de datos a través de la red) y eso puede generar confusión sobre la ejecución lenta del código así como problemas con la excepción de seguridad. –

+2

El operador [] también puede ocultar operaciones arbitrariamente complejas. – Ryan

+0

Entonces, solo si estamos usando estructuras de datos distintas a las matrices, lo mejor es usar los iteradores ¿verdad? – PrithviRaj

2

Existen muchas estructuras de datos, p. las tablas hash y las listas vinculadas no se pueden indexar de forma natural o rápida, pero sí son intercambiables. Los iteradores actúan como una interfaz que le permite caminar sobre cualquier estructura de datos sin conocer la implementación real de la fuente.

1

Al igual que los puntos en otras respuestas, los iteradores también pueden ser más rápidos (específicamente en comparación con operator[]), ya que son esencialmente iteración por puntero. Si haces algo como:

for (int i = 0; i < 10; ++i) 
{ 
    my_vector[i].DoSomething(); 
} 

Cada iteración del bucle calcula innecesariamente my_vector.begin() + i. Si usa iteradores, incrementar el iterador significa que ya apunta al siguiente elemento, por lo que no necesita ese cálculo adicional. Es algo pequeño, pero puede marcar la diferencia en los circuitos cerrados.

+0

No, un simple' + 'raramente toma muchos ciclos. – kennytm

+0

Todas las pruebas que he hecho indican que no existe una diferencia real en la velocidad entre los iteradores y op [] para los vectores. En todo caso, op [] es un poco más rápido. –

+0

@Neil: también he probado esto y he llegado a la conclusión de que los iteradores son * ligeramente * más rápidos. Sin embargo, tienes razón en que "no hay diferencia real". Y estoy seguro de que depende de la implementación. Probablemente probó en uno donde los iteradores no se implementaron de manera óptima ... –

2

de ampliar las respuestas anteriores:

  1. Grabación de un bucle con el operador [] se limita a un contenedor que admite [] y utiliza el mismo tipo de índice/tamaño. De lo contrario, necesitaría reescribir cada ciclo para cambiar el contenedor.

  2. Incluso si su contenedor admite [], puede que no sea óptimo para el desplazamiento secuencial. [] es básicamente un operador de acceso aleatorio, que es O (1) para el vector, pero podría ser tan malo como O (n) dependiendo del contenedor subyacente.

  3. Este es un punto menor, pero si usa iteradores, su bucle podría moverse más fácilmente a usar los algoritmos estándar, p. std :: for_each.

2

El STL contiene algoritmos, tales como transform y for_each que operan en los recipientes. No aceptan índices, pero usan iteradores.

Los iteradores ayudan a ocultar la implementación del contenedor y permiten que el programador se centre más en el algoritmo. La función for_each se puede aplicar a cualquier cosa que admita un iterador directo.

1

Otra pequeña diferencia es que no puede usar borrar() en un elemento en un vector por índice, debe tener un iterador. No es gran cosa ya que siempre puedes hacer "vect.begin() + index" como tu iterador, pero hay otras consideraciones. Por ejemplo, si hace esto, siempre debe verificar su índice con el tamaño() y no con alguna variable que le haya asignado ese valor.

Nada de eso es realmente demasiado vale la pena preocuparse, pero si se le da la opción, prefiero el acceso al iterador por las razones ya indicadas y esta.

1

Diría que es más una cuestión de consistencia y reutilización de código.

  • consistencia en que va a utilizar todos los otros recipientes con iteradores
  • la reutilización de código en que los algoritmos escrito para iteradores no puede ser utilizado con el operador subíndice y viceversa ... y el STL tiene un montón de algoritmos por lo que definitivamente desea construir sobre él.

Finalmente, me gustaría decir que incluso las matrices C tienen iteradores.

const Foo* someArray = //... 
const Foo* otherArray = new Foo[someArrayLength]; 

std::copy(someArray, someArray + someArrayLength, otherArray); 

La clase iterator_traits se ha especializado por lo que los punteros o un modelo de RandomAccessIterator.

Cuestiones relacionadas