Il semble que (2) ( autonome swap
dans le même espace de noms où la classe définie par l'utilisateur est déclarée ) soit le seul moyen autorisé de fournir swap
une classe définie par l'utilisateur, car l'ajout de déclarations à l'espace de noms std
est généralement un comportement non défini. Extension de l'espace de noms std (cppreference.com) :
L'ajout de déclarations ou de définitions à l'espace de noms std
ou à tout espace de noms imbriqué n'est pas défini std
, à quelques exceptions près notées ci-dessous
Et swap
ne fait pas partie de ces exceptions. Donc, ajouter votre propre swap
surcharge à l' std
espace de noms est un comportement indéfini.
Il est également dit que la bibliothèque standard utilise un appel non qualifié à la swap
fonction afin d'appeler défini swap
par l'utilisateur pour une classe d'utilisateurs si une telle définition utilisateur swap
est fournie.
Remplaçable (cppreference.com) :
De nombreuses fonctions de bibliothèque standard (par exemple, de nombreux algorithmes) s'attendent à ce que leurs arguments satisfassent Swappable , ce qui signifie que chaque fois que la bibliothèque standard effectue un échange, elle utilise l'équivalent de using std::swap; swap(t, u);
.
swap (www.cplusplus.com) :
De nombreux composants de la bibliothèque standard (dans std
) appellent swap
de manière non qualifiée pour permettre aux surcharges personnalisées pour les types non fondamentaux d'être appelées au lieu de cette version générique: Les surcharges personnalisées de swap
déclarées dans le même espace de noms que le type pour lequel elles sont fournies sont sélectionnées via une recherche dépendante des arguments sur cette version générique.
Mais notez que l'utilisation directe de la std::swap
fonction pour une classe définie par l'utilisateur appelle la version générique de std::swap
au lieu de celle définie par l'utilisateur swap
:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Il est donc recommandé d'appeler la swap
fonction en code utilisateur de la même manière que dans la bibliothèque 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.