Wydaje się, że (2) ( wolnostojący swap
w tej samej przestrzeni nazw, w której zadeklarowana jest klasa zdefiniowana przez użytkownika ) jest jedynym dozwolonym sposobem zapewnienia swap
klasy zdefiniowanej przez użytkownika, ponieważ dodawanie deklaracji do przestrzeni nazw std
jest zwykle niezdefiniowanym zachowaniem. Rozszerzenie przestrzeni nazw std (cppreference.com) :
Dodawanie deklaracji lub definicji do przestrzeni nazw std
lub do dowolnej przestrzeni nazw zagnieżdżonej w niej jest niezdefiniowanym zachowaniem std
, z kilkoma wyjątkami wymienionymi poniżej
I swap
nie jest oznaczony jako jeden z tych wyjątków. Zatem dodanie własnego swap
przeciążenia do std
przestrzeni nazw jest niezdefiniowanym zachowaniem.
Mówi się również, że biblioteka standardowa używa niekwalifikowanego wywołania swap
funkcji w celu wywołania zdefiniowanej swap
przez 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 swap
w 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 swap
zadeklarowane 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::swap
funkcji dla klasy zdefiniowanej przez użytkownika wywołuje ogólną wersję std::swap
zamiast zdefiniowanej przez użytkownika swap
:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Dlatego zalecane jest wywołanie swap
funkcji 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.