如何为我的课程提供交换function?

在STLalgorithm中启用swap的正确方法是什么?

1)会员swapstd::swap是否使用SFINAE技巧来使用成员swap

2)在相同的命名空间中独立swap

3)部分专业化的std::swap

4)以上全部。

谢谢。

编辑:看起来我没有清楚地说出我的问题。 基本上,我有一个模板类,我需要STLalgorithm使用我为这个类写的(高效)交换方法。

1)正确使用 swap 。 在编写“库”代码时要这样写,并且要在swap上启用ADL(参数相关查找)。 此外,这与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)是为class级提供swapfunction的正确方法。

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

如果现在使用如1)中所示的swap ,您的function将被find。 另外,如果您绝对需要,您可以将该函数设为朋友,或者提供免费函数调用的成员swap

 // 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)你的意思是明确的专业化。 部分仍然是别的东西,也不可能的function,只有结构/类。 因此,由于您不能专门为模板类使用std::swap ,所以您必须在您的名称空间中提供一个免费函数。 不是坏事,如果我可以这样说的话。 现在,明确的专业化也是可能的,但通常你不想专门化一个函数模板 :

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

4)不,因为1)与2)和3)不同。 而且,2)和3)都会导致总是被选中,因为它更合适。

要回答编辑,类可能是模板类,你根本不需要专业化。 考虑这样一个类:

 template <class T> struct vec3 { T x,y,z; }; 

你可以定义类如:

 vec3<float> a; vec3<double> b; vec3<int> c; 

如果你想创build一个函数来实现所有3个交换(不是这个例子类保证),你就像Xeo在(2)中所说的…没有专门化,只是做一个常规的模板函数:

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

交换模板函数应该与您要交换的类位于相同的名称空间中。 即使您没有使用ADL引用该名称空间,以下方法也会查找并使用该交换:

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