Должна ли std::vector:: swap() с помощью генераторов с сохранением состояния аннулировать все итераторы?

Указанные распределители a1 и a2, где a1!= a2,

и std::vector v1(a1) и v2(a2)

то v1.swap(v2) аннулирует все итераторы.

Является ли это ожидаемым поведением?

Ответ 1

В общем случае swap никогда не отменяет итераторов. Однако другое правило вступает в игру, когда распределители различны. В этом случае поведение зависит от allocator_traits<a1>::propagate_on_container_swap::value и allocator_traits<a2>::propagate_on_container_swap::value. Если оба значения истинны, распределители обмениваются вместе с данными, все итераторы остаются в силе. Если значение false, поведение undefined, поэтому допускается конкретное поведение, проявляемое VС++ 2010.

От [container.requirements.general] (формулировка от n3290):

Замена замены выполняется путем назначения копии, назначения перемещения или замены распределителя только в том случае, если allocator_traits<allocatortype>::propagate_on_container_copy_assignment::value, allocator_traits<allocatortype>::propagate_on_container_move_assignment::value или allocator_traits<allocatortype>::propagate_on_container_swap::value истинно в реализации соответствующей операции с контейнером. Поведение вызова функции обмена контейнерами - undefined, если только объекты, которые меняются местами, имеют распределители, сравнивающие равные или allocator_traits<allocatortype>::propagate_on_container_swap::value - true.

и

Каждый итератор, ссылающийся на элемент в одном контейнере перед свопом, должен ссылаться на тот же элемент в другом контейнере после обмена

и

Если не указано иное, функция no swap() делает недействительными любые ссылки, указатели или итераторы, ссылающиеся на элементы обменяемых контейнеров.

23.3.6.5 не определяет альтернативные правила для vector::swap().