Parece que (2) ( independente swap
no mesmo namespace onde a classe definida pelo usuário é declarada ) é a única maneira permitida de fornecer swap
uma 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 std
ou a qualquer namespace aninhado std
, com algumas exceções observadas abaixo
E swap
não é denotado como uma dessas exceções. Portanto, adicionar sua própria swap
sobrecarga ao std
namespace é um comportamento indefinido.
Também é dito que a biblioteca padrão usa uma chamada não qualificada para a swap
função a fim de chamar definido swap
pelo usuário para uma classe de usuário, se tal definido pelo usuário swap
for 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 swap
em 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 swap
declarada 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::swap
função para uma classe definida pelo usuário chama a versão genérica de em std::swap
vez 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 swap
funçã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.