Кажется, что (2) ( свободное положение swap
в том же пространстве имен, где объявлен определяемый пользователем класс ) является единственным допустимым способом предоставления swap
определяемого пользователем класса, поскольку добавление объявлений в пространство имен std
обычно является неопределенным поведением. Расширение пространства имен std (cppreference.com) :
Неопределенное поведение заключается в добавлении объявлений или определений в пространство имен std
или в любое пространство имен, вложенное в него std
, за некоторыми исключениями, указанными ниже.
И swap
не обозначается как одно из таких исключений. Поэтому добавление собственной swap
перегрузки в std
пространство имен - это неопределенное поведение.
Также сказано, что стандартная библиотека использует неквалифицированный вызов swap
функции для вызова swap
пользовательского класса для пользовательского класса, если такой пользовательский swap
предоставляется.
Возможность замены (cppreference.com) :
Многие стандартные библиотечные функции (например, многие алгоритмы) ожидают, что их аргументы будут соответствовать Swappable , что означает, что каждый раз, когда стандартная библиотека выполняет обмен, она использует эквивалент using std::swap; swap(t, u);
.
своп (www.cplusplus.com) :
Многие компоненты стандартной библиотеки (в std
) вызове swap
в качестве неквалифицированным образом , чтобы пользовательские перегрузок для неосновных видов называться вместо этого дженерик: Пользовательские перегруженных swap
объявленные в том же пространстве имен типа , для которых они предоставляются выбраны через поиск, зависящий от аргументов, в этой универсальной версии.
Но обратите внимание, что прямое использование std::swap
функции для пользовательского класса вызывает общую версию std::swap
вместо пользовательской swap
:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Поэтому рекомендуется вызывать swap
функцию в пользовательском коде так же, как это делается в стандартной библиотеке:
my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.