考虑写出一个不抛出异常的swap函数

来源:互联网 发布:电影院订票系统 php 编辑:程序博客网 时间:2024/05/01 12:27

1、当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常。

2、如果你提供一个member swap函数,也该提供一个non-member swap函数,后者用来调用前者。对于class(而非template),也请特化std::swap

3、调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰”。

4、为“用户定义类型”进行std template全特化是好的,但千万不要尝试在std内加入某些对std而言全新的东西。


如swap的缺省实现对你的class或者class template提供可接受的效率,你不需要额外做任何事情,任何尝试置换(swap)那种对象的人都会取得缺省版本,而那将有良好的运作。

其次,如果swap缺省实现版本的效率不足(那几乎总是以为你的class或者class template使用了某种pimpl【pointer 头implement】手法),尝试做以下 的事情:

1、提供一个public swap成员函数,让他高效的置换(swap)你的类型的两个对象值。

2、在你的class或者是template所在的命名空间内提供一个non-member swap函数,并令他调用上述swap函数(member swap函数)。

3、如果你正在编写一个class(而不是class template),为你的class特化std::swap。并令他调用你的swap成员函数。

最后,如果你调用swap函数,请确定包含一个using声明式,以便让std::swap在你的函数内曝光可见,然后不加任何namespace修饰符,赤裸裸的调用swap。


namespace std{

template<typename T>

void swap(T &a,T&b)

{

T temp(a);

a=b;

b=temp;

}

}

只要类型T支持copying(通过copy构造函数和copy assignment操作符完成)。


class AImpl{

public:

private:

int a,b,c;

std::vector<double> v;      //可能有许多的数据,意味着copy的时间很长

}


class A{

public:

A(const A& rhs);

A& operator=(const A&rhs)

{

*pImpl = *(rhs.pImpl);

}

private:

AImpl *pImpl;

}


一旦要置换两个A对象,使用std::swap赋值的不仅仅是*pImpl对象,还有很多其他的对象,浪费。。。


特化版本:

namespace std{

template<>

void swap<A>(A &a, A&b)

{

swap(a.pImpl,b.pImpl);

}

}


”template<>“表示他是std::swap的一个全特化的版本。

class A{

public:

void swap(A *other)

{

using std::swap;

swap(pImpl,other.pImpl);

}

}

namespace std{

template<>

void swap<A>(A &a,A&b)

{

a.swap(b);

}

}


template<typename T>

class AImpl{...};

template<typename T>

class A{

........

};


name std{

template<typename T>

void swap<A<T>>( A<T>&a,A<T>&b)   //错误,不合法

{

a.swap(b);

}

}

解决办法:

namespace AStuff{

template<typename T>

class A{....};

template<typename T>

void swap(A<T> &a,A<T>&b)

{

a.swap(b);

}

}


template<typename T>

void dosomething(T &a,T&b)

{

using std::swap;

swap(a,b);

}


原创粉丝点击