Parece que (2) ( independente swapno mesmo namespace onde a classe definida pelo usuário é declarada ) é a única maneira permitida de fornecer swapuma classe definida pelo usuário, porque adicionar declarações ao namespace stdé geralmente um comportamento indefinido. Estendendo o namespace std (cppreference.com) :
É um comportamento indefinido adicionar declarações ou definições ao namespace stdou a qualquer namespace aninhado std, com algumas exceções observadas abaixo
E swapnão é denotado como uma dessas exceções. Portanto, adicionar sua própria swapsobrecarga ao stdnamespace é um comportamento indefinido.
Também é dito que a biblioteca padrão usa uma chamada não qualificada para a swapfunção a fim de chamar definido swappelo usuário para uma classe de usuário, se tal definido pelo usuário swapfor fornecido.
Swappable (cppreference.com) :
Muitas funções de biblioteca padrão (por exemplo, muitos algoritmos) esperam que seus argumentos satisfaçam Swappable , o que significa que sempre que a biblioteca padrão realiza uma troca, ela usa o equivalente de using std::swap; swap(t, u);.
swap (www.cplusplus.com) :
Muitos componentes da biblioteca padrão (dentro std) chamada swapem uma inqualificável forma a permitir sobrecargas personalizadas para tipos não-fundamentais para ser chamado em vez desta versão genérica: sobrecargas personalizados de swapdeclarada no mesmo espaço de nomes como o tipo para o qual são fornecidas selecionado por meio de pesquisa dependente de argumento sobre esta versão genérica.
Mas observe que usar diretamente a std::swapfunção para uma classe definida pelo usuário chama a versão genérica de em std::swapvez da definida pelo usuário swap:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Portanto, é recomendável chamar a swapfunção no código do usuário da mesma forma que é feito na biblioteca padrão:
my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.