Sembra che (2) ( free standing swapnello stesso spazio dei nomi in cui è dichiarata la classe definita dall'utente ) sia l'unico modo consentito per fornire swapuna classe definita dall'utente, perché l'aggiunta di dichiarazioni allo spazio dei nomi stdè generalmente un comportamento indefinito. Estensione dello spazio dei nomi std (cppreference.com) :
È un comportamento indefinito aggiungere dichiarazioni o definizioni allo spazio dei nomi stdo a qualsiasi spazio dei nomi annidato all'interno std, con alcune eccezioni indicate di seguito
E swapnon è indicato come una di quelle eccezioni. Quindi l'aggiunta del proprio swapoverload allo stdspazio dei nomi è un comportamento indefinito.
Si dice anche che la libreria standard utilizzi una chiamata non qualificata alla swapfunzione per chiamare definita swapdall'utente per una classe utente se swapviene fornita tale definita dall'utente .
Scambiabile (cppreference.com) :
Molte funzioni della libreria standard (ad esempio, molti algoritmi) si aspettano che i loro argomenti soddisfino Swappable , il che significa che ogni volta che la libreria standard esegue uno scambio, utilizza l'equivalente di using std::swap; swap(t, u);.
swap (www.cplusplus.com) :
Molti componenti della libreria standard (all'interno std) chiamano swapin modo non qualificato per consentire la chiamata di overload personalizzati per tipi non fondamentali invece di questa versione generica: vengono selezionati gli overload personalizzati swapdichiarati nello stesso spazio dei nomi del tipo per cui sono forniti attraverso la ricerca dipendente dall'argomento su questa versione generica.
Ma si noti che l'utilizzo diretto della std::swapfunzione per una classe definita dall'utente chiama la versione generica di std::swapinvece di quella definita dall'utente swap:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Quindi si consiglia di chiamare la swapfunzione nel codice utente nello stesso modo in cui si fa nella libreria standard:
my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.