2008-09-27 23 views
10

La forma de 3 argumentos de list::splice() mueve un solo elemento de una lista a la otra. SGI's documentation establece explícitamente que todos los iteradores, incluyendo el que apunta al elemento que se mueve siguen siendo válidos. Roguewave's documentation no dice nada sobre las propiedades de invalidación del iterador de los métodos splice(), mientras que el estándar C++ establece explícitamente que invalida todos los iteradores y las referencias al elemento que se empalma.empalme() en std :: list e invalidación de iterador

splicing() funciona en la práctica como lo define SGI, pero obtengo una falla de aserción (desreferenciación del iterador no válido) en las versiones depug/secure SCL de la implementación STL de microsoft (que sigue estrictamente la letra del estándar).

Ahora, estoy usando list exactamente porque quiero mover un elemento entre listas, mientras se preserva la validez del iterador que lo señala. El estándar ha hecho un cambio extremadamente inútil a la especificación original de SGI.

¿Cómo puedo evitar este problema? ¿O debería ser simplemente pragmático y meter la cabeza en la arena (porque el empalme no no invalida iteradores en la práctica, ni siquiera en la implementación del MS, una vez que la depuración del iterador está desactivada).

+0

Una gran pregunta. ¿Cuál fue la última palabra? –

+0

El estándar es estúpido, pero correcto. No use empalmes en programas que se ajusten a las normas. Tal vez C++ 1x enmendó la situación; No lo he comprobado – zvrba

+5

Acabo de verificar, cambia. La redacción retenida es la del defecto 250 de LWG: los iteradores anteriores son válidos y se comportan como si apuntaran al nuevo contenedor. –

Respuesta

9

Ok, esto parece ser un defecto en el estándar, de acuerdo con this y this enlace. Parece que "meter la cabeza en la arena" es una buena estrategia, ya que se solucionará en las nuevas versiones de la biblioteca.

2

El problema es que si el iterador aún apunta al elemento que se movió, entonces el iterador "final" asociado previamente con el iterador "movido" ha cambiado. A menos que escriba algún ciclo complejo, esto es realmente algo malo, especialmente porque será más difícil de entender para otros desarrolladores.

Una mejor manera en mi opinión es utilizar los iteradores que apuntan a los elementos antes y después del iterador movido.

+0

Depende de si mantiene iteradores para acceder a los elementos sin perder la capacidad de manipulación de la lista o si actualmente está iterando sobre la lista, en cuyo caso tendrá que tener cuidado. – Fruny

0

Tengo una matriz de listas (clases de equivalencia de elementos), y estoy usando empalme para mover elementos entre las listas. Tengo una matriz adicional de iteradores que me da acceso directo a cualquier elemento en cualquiera de las listas y moverlo a otra lista. Ninguna de las listas se busca y modifica al mismo tiempo. I podría reiniciar el elemento iterador después del empalme, pero es un poco feo ... Supongo que lo haré por el momento.

Cuestiones relacionadas