2010-07-08 16 views
17

La documentación para specialized iterator adaptors de boost indica que boost::reverse_iterator "Corrige muchas de las deficiencias de std :: reverse_iterator de C++ 98".¿Cuáles son las deficiencias de std :: reverse_iterator?

¿Cuáles son estas deficiencias? Parece que no puedo encontrar una descripción de estas deficiencias.

SEGUIMIENTO PREGUNTA:

¿Cómo impulso :: reverse_iterator corregir estas deficiencias?

+1

A menudo era un poco ..... prematuro. –

+0

Publicando un comentario ya que solo estoy adivinando: las primeras implementaciones de 'std :: reverse_iterator <>' a veces tenían errores. Boost puede haber estado simplemente tratando de aislarse de esa situación. Tal vez el comentario es más acerca de las deficiencias en las implementaciones 'reverse_iterator' en lugar de las deficiencias en el estándar? –

Respuesta

10

Bueno, el gran problema es que no son iteradores directos, y hay cosas que casi esperan iteradores directos. Entonces, tienes que hacer algunas conversiones graciosas para que las cosas funcionen. Para nombrar algunos problemas

  1. algunas versiones de erase() y insert() requieren iteradores en lugar de iteradores inversa. Eso significa que si está utilizando un iterador inverso y quiere insert() o erase(), tendrá que usar la función base() del iterador inverso para tener en sus manos un iterador directo. No hay conversión automática

  2. base() devuelve el iterador directo equivalente al repetidor inverso en términos de inserción. Es decir, inserte inserciones delante del elemento actual. El elemento al que apunta el iterador inverso, por lo tanto, sería el elemento incorrecto para señalar si base() le dio un iterador que apuntaba al mismo elemento. Por lo tanto, apunta uno hacia adelante y puede usarlo para insertarlo.

  3. Dado que base() devuelve un iterador que apunta a un elemento diferente, es el elemento incorrecto para usar para erase(). Si llamó al erase() en el iterador desde base(), borrará un elemento hacia adelante en el contenedor del elemento al que apunta el iterador inverso, por lo que debe aumentar el iterador inverso antes de llamar al base() para obtener el iterador correcto hacia adelante. usar para erase().

  4. Si puede incluso usar base() con erase() para borrar correctamente un elemento, depende completamente de su implementación. Funciona con gcc, pero con Visual Studio solo están envolviendo un iterador directo de una manera que hace que no funcione usar erase() cuando se trata de iteradores inversos y Visual Studio. No recuerdo si insert() tiene el mismo problema, pero los iteradores inversos no funcionan igual entre las diferentes implementaciones de C++ (según los chicos de Visual Studio, el estándar no era lo suficientemente claro), por lo que puede ser bastante peludo. para usarlos para cualquier cosa que no sea simplemente iterar sobre un contenedor.

Probablemente hay otros problemas también, pero se trata de cualquier tipo de iterador que no sea un no constante, iterador hacia adelante en C++ cuando se hace que no sea simplemente la iteración en un recipiente que cualquier cosa puede ser un poco peluda - si incluso puede hacerlo todo porque muchas funciones requieren iteradores no const en lugar de cualquier otro tipo de iterador.

Si realmente desea saber las diferencias entre los diversos tipos de iteradores y los problemas asociados con ellos, le recomiendo leer de Scott Meyer Effective STL. Tiene un gran capítulo sobre iteradores.

EDIT: En cuanto a cómo el iterador inverso de Boost corrige esas deficiencias, me temo que no tengo ni idea. Estoy al tanto de algunas de las deficiencias estándar del iterador inverso y me han mordido en el pasado, pero nunca he usado Boost mucho, así que no estoy familiarizado con sus iteradores inversos. Lo siento.

+1

No estoy seguro de ver a qué te refieres. El código que "espera" que los iteradores directos no "noten" ninguna diferencia a menos que hagan cosas con un comportamiento indefinido ... – Cogwheel

+1

La plantilla 'std :: reverse_iterator' en C++ 03 expone la misma categoría de iterador que el iterador subyacente que debe ser al menos un iterador bidireccional, por lo que un reverse_iterator siempre es al menos un iterador bi-di (y por lo tanto un iterador directo). –

+1

No creo que estés en lo correcto aquí. Creo que un reverse_iterator es, de hecho, un iterador directo. Al menos no veo dónde viola ese concepto. –

Cuestiones relacionadas