如何为我的课程提供交换function?
在STLalgorithm中启用swap
的正确方法是什么?
1)会员swap
。 std::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级提供swap
function的正确方法。
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);