comment fournir une fonction d’échange pour ma classe?

Quelle est la bonne façon d’activer mon swap dans les algorithmes STL?

1) swap membre. Est-ce que std::swap utilise le truc SFINAE pour utiliser le swap membre.

2) Echange libre dans le même espace de noms.

3) Spécialisation partielle de std::swap .

4) Tout ce qui précède.

Je vous remercie.

EDIT: On dirait que je n’ai pas prononcé ma question clairement. Fondamentalement, j’ai une classe de template et j’ai besoin d’algos STL pour utiliser la méthode de swap (efficace) que j’ai écrite pour cette classe.

1) est le bon usage du swap . Écrivez-le de cette manière lorsque vous écrivez du code “bibliothèque” et que vous souhaitez activer la recherche ADL (dépendante des arguments) sur le swap . De plus, cela n’a rien à voir avec SFINAE.

 // some algorithm in your code template 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-ce la bonne façon de fournir une fonction d’ swap pour votre classe.

 namespace Foo{ class Bar{}; // dummy void swap(Bar& lhs, Bar& rhs){ // ... } } 

Si swap est maintenant utilisé comme indiqué dans 1), votre fonction sera trouvée. Vous pouvez également faire de cette fonction un ami si vous en avez absolument besoin ou fournir un swap membre appelé par la fonction gratuite:

 // 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 une spécialisation explicite. Partiel est encore autre chose et n’est pas possible non plus pour les fonctions, mais uniquement pour les structures / classes. En tant que tel, puisque vous ne pouvez pas spécialiser std::swap pour les classes de modèle, vous devez fournir une fonction gratuite dans votre espace de noms. Pas une mauvaise chose, si je puis dire. Maintenant, une spécialisation explicite est également possible, mais vous ne souhaitez généralement pas spécialiser un modèle de fonction :

 namespace std { // only allowed to extend namespace std with specializations template<> // specialization void swap(Bar& lhs, Bar& rhs){ // ... } } 

4) Non, comme 1) est distinct de 2) et 3). En outre, avoir les deux) et 3) mènera à toujours avoir 2) cueillies, parce que ça va mieux.

Pour répondre à l’EDIT, où les classes peuvent être des classes de modèle, vous n’avez pas besoin de spécialisation. considérez une classe comme celle-ci:

 template  struct vec3 { T x,y,z; }; 

vous pouvez définir des classes telles que:

 vec3 a; vec3 b; vec3 c; 

Si vous voulez être en mesure de créer une fonction pour implémenter les 3 swaps (mais pas que cette classe d’exemple le garantisse), faites comme Xeo dans (2) … sans spécialisation, mais créez simplement une fonction de template:

 template  void swap(vec3 &a, vec3 &b) { using std::swap; swap(ax,bx); swap(ay,by); swap(az,bz); } 

La fonction de modèle de swap doit être située dans le même espace de noms que la classe que vous essayez de permuter. La méthode suivante trouvera et utilisera ce swap même si vous ne faites pas référence à cet espace de noms en utilisant ADL:

 using std::swap; swap(a,b);