Splice() в std:: list и аннулирование итератора

Форма с тремя аргументами list::splice() перемещает один элемент из одного списка в другой. Документация SGI явно заявляет, что все итераторы, в том числе те, которые указывают на перемещаемый элемент, остаются в силе. Документация Roguewave не говорит ничего о свойствах аннулирования итератора методов splice(), тогда как в стандарте С++ явно указано, что он аннулирует все итераторы и ссылки на элемент сплайсируется.

splicing() на практике работает как определено SGI, но я получаю отказ от утверждения (разыменование недействительного итератора) в debug/secure SCL версиях реализации Microsoft STL (что строго следует букве стандарта).

Теперь я использую список именно потому, что хочу переместить элемент между списками, сохраняя при этом правильность итератора, указывающего на него. Стандарт внес чрезвычайно бесполезное изменение в оригинальную спецификацию SGI.

Как я могу обойти эту проблему? Или я просто должен быть прагматичным и придерживаться головы в песке (потому что сращивание делает не недействительными итераторы на практике - даже в реализации MS, после отладки итератора отключается).

Ответ 1

Хорошо, это кажется дефектом в стандарте, согласно this и this. Похоже, что "прилипание головы в песок" - хорошая стратегия, поскольку она будет исправлена ​​в новых версиях библиотеки.

Ответ 2

Проблема в том, что если итератор все еще указывает на перемещенный элемент, то итератор "end", ранее связанный с "перемещенным" итератором, изменился. Если вы не напишете сложный цикл, на самом деле это плохо, потому что это будет труднее понять другим разработчикам.

Лучше, на мой взгляд, использовать итераторы, указывающие на элементы до и после перемещенного итератора.

Ответ 3

У меня есть массив списков (классы эквивалентности элементов), и я использую splice для перемещения элементов между списками. У меня есть дополнительный массив итераторов, который дает мне прямой доступ к любому элементу в любом из списков и переместить его в другой список. Ни один из списков не просматривается и не изменяется одновременно. Я мог бы повторить инициализацию итератора элементов после сращивания, но это немного уродливо. Наверное, я сделаю это пока.