写一个不抛异常的swap函数

Consider support for a non-throwing swap.

STL中的swap算法:

namespace std{

template<typename T>

void swap(T& a,T& b)

{

T temp(a);

a=b;

b=temp;

}

}

 

复制动作无一必要。

考虑以指针指向一个对象,内含真正数据。

class WidgetImpl{

public:

...

private:

int a,b,c;                         //可能有许多数据,

std::vector<double> v;  //意味复制时间很长

...

};

 

以下class使用pimpl(pointer to implementation)方法:

class Widget{

public:

Widget(const Widget& rhs);

Widget& operator=(const  Widget& rhs)

{

...

*pImpl=*(rhs.pImpl);

...

}

...

private:

WindgetImpl* pImpl; //指针,所指对象内含widget数据

};

 

一旦要置换两个widget对象值,只需要置换pImpl指针。缺省的swap算法得复制三个Widgets,三个WidgetImpl.

 

将std::swap针对Widget特化:

namespace std{

template<>                                                   //全特化:total template specialization

void swap<Widget>(Widget& a,Widget& b)      //<Widget>表示特化系对"T 是Widget"而设计

{

swap(a.pImpl,b,pImpl);

}

}

 

无法通过编译,指针为private.
我尝试用member function取代。
假如Widget和widgetImpl都是class template:

namespace std{
template<typename T>
void swap<Widget<T>>(Widget<T>& a,Widget<T>& b)
{a.swap(b);}
}
c++只允许class template偏特化(partially specialize,function template行不通。
试着重载:
namespace std{
template<typename T>
void(Widget<T>& a,Widget<T>& b)
{a.swap(b);}
}
重载没有问题,但是std的内容完全由C++标准委员会决定,不可随意添加。

可以声明一个non-member swap调用member swap,但不再将non-member声明为特化版本或重载版本。
namespace WidgetStuff{
...
template<typename T>
class Widget{...};
...
template<typename T>
void swap(Widget<T>& a,Widget<T>& b)
{a.swap(b);}
}

现在任何地点任何代码如果打算置换两个Widget对象,调用swap,c++名称查找法则(name lookup rules;
更具体地说是所谓的argument-dependent lookup或Koenig lookup法则)会找到WidgetStuff内的Widget专属版本。

我们希望调用T专属版本,并在该版本不存在的情况下调用一般化版本。

template<typename T>
void doSomething(T& obj1,T& obj2)
{
usingstd::swap;
...
swap(obj1,obj2);
...
}

一旦编译器看到swap的调用,便查找适当的swap调用。C++名称查找法则确保将global作用域或T所在的命名空间内的任何T专属的swap.

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值