Ответ 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()
.