boost::swap是对标准库里的std::swap的增强和泛化,为交换两个变量的值提供便捷的方法。
为了使用需包含头文件: #include <boost/swap.hpp>
原理
c98标准中的std::swap():
template<typename T>
void swap(T& a,T& b)
{
T tmp(a);
a = b;
b = temp;
}
在标准库的swap中,要求交换的对象必须是可拷贝构造和可拷贝赋值的,效率低,需要进行一次复制构造和两次赋值操作。c++11标准使用转移语义对std::swap()进行优化:
template<typename T>
void swap(T& a,T& b)
{
T tmp = std::move(a); //把a'偷'到tmp
a = std::move(b); //把b'偷'到a
b = std::move(tmp); //把tmp'偷'到b
}
但不是所有的类都实现了自己的状态转移构造和赋值函数的,而且编译器的支持也是个必须考虑的问题,因此对于我们写的类,最好能够实现优化的swap()来提高效率。
解决方案有两种:一种是直接利用函数重载,编写同名的swap函数,调用函数的高校成员交换函数,不会使用标准库的swap,第二种是使用ADL(参数依赖查找)查找模板特化的std::swap()。
boost::查找有无针对类型T的std::swap()的特化或通过ADL查找模板特化的swap(),如果有则调用,查找失败则退化为std::swap();由于boost::swap() 和std::swap()同名,所以我们不能用using打开boost名字空间,应该用boost名字空间限定的方式调用它。
int al[10],a2[12]; //两个不通长度的数组
boost::swap(al,a2) //编译错误
特化的std::swap()--以简单的三维空间节点交换为例子,运用模板特化的方法使用boost::swap():
#include <boost/swap.hpp>
#include <ostream>
using namespace std;
class point
{
int x,y,z;
public:
explict point(int a=0,int b=0,int c=0): x(a),y(b),z(c) {}
void swap(point &p)
{
std::swap(x,p.x);
std::swap(y,p.y);
std::swap(z,p.z);
cout<<"inner swap"<<endl
}
};
namespace std{
template<>
void swap(point &x,point &y)
{ x.swap(y); }
}
int main()
{
point a(1,2,3),b(4,5,6);
cout<<"std::swap"<<endl;
std::swap(a,b);
cout<<"boost::swap"<<endl;
boost::swap(a,b);
}
//运行结果:
std::swap
inner swap
boost::swap
inner swap
由于我们在名字空间特化了std::swap,因此boost::swap和std::swap调用结果是相同的,都使用了特化后的swap函数。
特化ADL可找到的swap
唯一改动的是实现全局域的swap函数:
#include <boost/swap.hpp>
#include <ostream>
using namespace std;
class point
{
int x,y,z;
public:
explict point(int a=0,int b=0,int c=0): x(a),y(b),z(c) {}
void swap(point &p)
{
std::swap(x,p.x);
std::swap(y,p.y);
std::swap(z,p.z);
cout<<"inner swap"<<endl
}
};
void swap(point & x,point& y)
{
x.swap(y);
}
int main()
{
point a(1,2,3),b(4,5,6);
cout<<"std::swap"<<endl;
std::swap(a,b);
cout<<"boost::swap"<<endl;
boost::swap(a,b);
}
//运行结果:
std::swap
boost::swap
inner swap
与之前的特化std::swap不同,std::swap使用了标准的交换操作,而boost::swap通过ADL规则找到全局名字空间的特化交换函数,实现高效的交换。
原文:https://www.cnblogs.com/kloseer/p/12069506.html