Wydaje się, że (2) ( wolnostojący swapw tej samej przestrzeni nazw, w której zadeklarowana jest klasa zdefiniowana przez użytkownika ) jest jedynym dozwolonym sposobem zapewnienia swapklasy zdefiniowanej przez użytkownika, ponieważ dodawanie deklaracji do przestrzeni nazw stdjest zwykle niezdefiniowanym zachowaniem. Rozszerzenie przestrzeni nazw std (cppreference.com) :
Dodawanie deklaracji lub definicji do przestrzeni nazw stdlub do dowolnej przestrzeni nazw zagnieżdżonej w niej jest niezdefiniowanym zachowaniem std, z kilkoma wyjątkami wymienionymi poniżej
I swapnie jest oznaczony jako jeden z tych wyjątków. Zatem dodanie własnego swapprzeciążenia do stdprzestrzeni nazw jest niezdefiniowanym zachowaniem.
Mówi się również, że biblioteka standardowa używa niekwalifikowanego wywołania swapfunkcji w celu wywołania zdefiniowanej swapprzez użytkownika klasy użytkownika, jeśli taka zdefiniowana przez użytkownikaswap jest dostarczona.
Możliwość wymiany (cppreference.com) :
Wiele funkcji bibliotek standardowych (na przykład wiele algorytmów) oczekuje, że ich argumenty spełnią wymagania Swappable , co oznacza, że za każdym razem, gdy biblioteka standardowa wykonuje zamianę, używa odpowiednika using std::swap; swap(t, u);.
swap (www.cplusplus.com) :
Wiele składników biblioteki standardowej (w ramach std) wywołuje swapw niekwalifikowany sposób, aby umożliwić wywoływanie niestandardowych przeciążeń dla typów innych niż podstawowe zamiast tej wersji ogólnej: Niestandardowe przeciążenia swapzadeklarowane w tej samej przestrzeni nazw, co typ, dla którego są dostarczane, są wybierane poprzez wyszukiwanie zależne od argumentów w tej wersji ogólnej.
Zwróć jednak uwagę, że bezpośrednie użycie std::swapfunkcji dla klasy zdefiniowanej przez użytkownika wywołuje ogólną wersję std::swapzamiast zdefiniowanej przez użytkownika swap:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Dlatego zalecane jest wywołanie swapfunkcji w kodzie użytkownika w taki sam sposób, jak to się robi w standardowej bibliotece:
my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.