splice () при аннулировании std :: list и итератора - PullRequest
10 голосов
/ 27 сентября 2008

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

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

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

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

Ответы [ 3 ]

9 голосов
/ 27 сентября 2008

Хорошо, похоже, это дефект в стандарте, согласно этой и этой ссылке. Кажется, что «засовывать голову в песок» - это хорошая стратегия, поскольку она будет исправлена ​​в новых версиях библиотеки.

2 голосов
/ 27 сентября 2008

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

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

0 голосов
/ 27 сентября 2008

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

...