Sembra che (2) ( free standing swap
nello stesso spazio dei nomi in cui è dichiarata la classe definita dall'utente ) sia l'unico modo consentito per fornire swap
una 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 std
o a qualsiasi spazio dei nomi annidato all'interno std
, con alcune eccezioni indicate di seguito
E swap
non è indicato come una di quelle eccezioni. Quindi l'aggiunta del proprio swap
overload allo std
spazio dei nomi è un comportamento indefinito.
Si dice anche che la libreria standard utilizzi una chiamata non qualificata alla swap
funzione per chiamare definita swap
dall'utente per una classe utente se swap
viene 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 swap
in modo non qualificato per consentire la chiamata di overload personalizzati per tipi non fondamentali invece di questa versione generica: vengono selezionati gli overload personalizzati swap
dichiarati 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::swap
funzione per una classe definita dall'utente chiama la versione generica di std::swap
invece 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 swap
funzione 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.