1) est à la bonne utilisation de l' swap
. L'écrire de cette façon, lorsque vous écrivez "bibliothèque" de code et souhaitez activer l'ADL (argument-dépendante de recherche) swap
. Aussi, cela n'a rien à voir avec SFINAE.
// some algorithm in your code
template<class T>
void foo(T& lhs, T& rhs){
using std::swap; // enable 'std::swap' to be found
// if no other 'swap' is found through ADL
// some code ...
swap(lhs, rhs); // unqualified call, uses ADL and finds a fitting 'swap'
// or falls back on 'std::swap'
// more code ...
}
2) Est la bonne façon de fournir un swap
fonction de votre classe.
namespace Foo{
class Bar{}; // dummy
void swap(Bar& lhs, Bar& rhs){
// ...
}
}
Si swap
est maintenant utilisé comme indiqué en 1), votre fonction sera trouvé. Aussi, vous pouvez faire que la fonction d'un ami si vous en avez absolument besoin, ou de fournir un membre de l' swap
qui est appelée par la fonction:
// version 1
class Bar{
public:
friend void swap(Bar& lhs, Bar& rhs){
// ....
}
};
// version 2
class Bar{
public:
void swap(Bar& other){
// ...
}
};
void swap(Bar& lhs, Bar& rhs){
lhs.swap(rhs);
}
3) Vous voulez dire explicitement spécialisation. Partielle est encore autre chose et pas possible pour les fonctions, seulement des structures / classes. En tant que tel, puisque vous ne pouvez pas se spécialisent std::swap
pour les classes template, vous avez pour fournir une fonction libre dans votre espace de noms. Pas une mauvaise chose, si je puis dire. Maintenant, explicite la spécialisation est également possible, mais en général, vous ne voulez pas de se spécialiser un modèle de fonction:
namespace std
{ // only allowed to extend namespace std with specializations
template<> // specialization
void swap<Bar>(Bar& lhs, Bar& rhs){
// ...
}
}
4) N, 1) est distinct de 2) et 3). Aussi, ayant à la fois 2) et 3) permettra d'avoir toujours 2) choisi, parce qu'il va mieux.