Il semble que (2) ( autonome swapdans 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 swapune classe définie par l'utilisateur, car l'ajout de déclarations à l'espace de noms stdest 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 stdou à tout espace de noms imbriqué n'est pas défini std, à quelques exceptions près notées ci-dessous
Et swapne fait pas partie de ces exceptions. Donc, ajouter votre propre swapsurcharge à l' stdespace de noms est un comportement indéfini.
Il est également dit que la bibliothèque standard utilise un appel non qualifié à la swapfonction afin d'appeler défini swappar l'utilisateur pour une classe d'utilisateurs si une telle définition utilisateur swapest 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 swapde 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 swapdé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::swapfonction pour une classe définie par l'utilisateur appelle la version générique de std::swapau 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 swapfonction 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.