Поведение подкачки было значительно разъяснено в C ++ 11, в значительной степени, чтобы позволить алгоритмам стандартной библиотеки использовать аргумент-зависимый поиск (ADL) для поиска функций подкачки для пользовательских типов.C ++ 11 добавляет концепцию swappable (C ++ 11 §17.6.3.2 [swappable.requirements]), чтобы сделать это законным (и обязательным).
Текст в C +Языковым стандартом +11, который отвечает на ваш вопрос, является следующий текст из требований к контейнерам (§23.2.1 [container.requirements.general] / 8), который определяет поведение функции-члена swap
контейнера:
Каждый итератор, ссылающийся на элемент в одном контейнере до свопа, должен ссылаться на тот же элемент в другом контейнере после свопа.
Не определено, является ли итератор со значением a.end()
переду свопа будет значение b.end()
после свопа.
В вашем примере a
гарантированно будет действительным после свопа, но b
не потому, что это конечный итератор.Причина, по которой конечные итераторы не гарантируются как действительные, объясняется в примечании к §23.2.1 / 10:
[Примечание: итератор end()
не ссылается ни на один элемент, поэтому можетбыть признанным недействительным- end note]
Это то же самое поведение, которое определено в C ++ 03, только существенно разъяснено.Исходный язык C ++ 03 находится на C ++ 03 §23.1 / 10:
no swap()
Функция делает недействительными любые ссылки, указатели или итераторы, ссылающиеся на элементы переставляемых контейнеров..
Это не сразу очевидно в исходном тексте, но фраза "элементам контейнеров" чрезвычайно важна, поскольку итераторы end()
не указывают на элементы.