Я не думаю, что для вектора разрешено использовать swap
(найдено ADL). Я не могу явно найти то, что могу найти, но требования к типу значения vector: CopyConstructible и Assignable. Ни один из них не имеет swap
в качестве допустимой операции (даже необязательной), ни какой-либо стандартный способ определить, перегружен ли своп или нет. Возможно, он мог бы использовать std::swap
(или специализацию, если таковая существует), где это уместно, потому что к его параметрам предъявляются одинаковые требования: CopyConstructible и Assignable (и специализации для UDT функций в пространстве имен std должны реализовывать определенное поведение универсального шаблон). Это не помогает с перераспределением, потому что вам нужно создать несколько «пустых» объектов для обмена, и вектор не может просто решить из своего собственного авторитета, что его тип значения должен быть конструируемым по умолчанию, когда стандарт не этого не требуется.
Я думаю, что разумно предположить, что если операция не требуется для вашего типа T, то она не будет выполнена, даже если компилятор каким-то образом психически определит, что она существует. В C ++ то, что у чего-то есть правильные функции, определенные для реализации интерфейса, не означает, что он претендует на реализацию семантики этого интерфейса. Пока вы не передадите его в контекст, требующий семантики, вы заявляете, что поведение функций соответствует интерфейсу. Стандарт не требует хорошего поведения swap
для типа значения вектора, поэтому реализация вектора не может предполагать, что только из-за того, что определено swap
, оно лучше, чем operator=
.
Это только моя интерпретация намерения спецификации, хотя я не могу найти ничего определенного в любом случае.
23.2.4.3 / 4 дает подсказку. Говоря о erase
, он говорит: «Оператор присваивания T называется числом раз, равным количеству элементов в векторе после стертых элементов». Поэтому vector явно запрещено использовать swap
для смещения конца вектора после стирания: он должен использовать operator=
. Я воспринимаю это как сильный намек на то, что авторы ожидают использовать operator=
для всего, в противном случае они не были бы столь небрежными, чтобы запретить swap
в одном случае, когда его фактически можно использовать без какой-либо необходимости конструктор по умолчанию.
Я также вижу точку зрения Microsoft, описанную вами и jdv, о том, что для контейнеров контейнеров можно получить большую выгоду от обмена. Пока «волшебство шаблона» таково, что оно не мешает правильно сформированным программам на C ++, нет ничего плохого в реализации, предоставляющей средства для типов для указания вектора на обмен.
Например, возможно, у них есть шаблон признаков типа с двойным подчеркиванием в имени. Эффект от использования этого имени определяется реализацией, поэтому все ставки отключены. Стандарт C ++ ничего не говорит о том, как std :: vector ведет себя в программах, которые специализируются на этом шаблоне. После того как вы использовали зарезервированное имя в своей программе, реализация может определить vector, чтобы использовать operator=
, swap
или aubergine
для всех стандартных операций.