boost::swap
2024-08-27 04:58:14
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名字空间限定的方式调用它。
交换数组
boost::swap()可以直接交换两个数组的内容,但要求参与交换的两个数组必须是具有相同的长度。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规则找到全局名字空间的特化交换函数,实现高效的交换。
最新文章
- 关于composer安装插件时候提示找不到fxp插件时候的解决办法
- 承接Hololens游戏外包
- 谷歌联合 Adobe 发布 Noto 字体【免费下载】
- Java--继承和super关键字
- Mysql数据数据[字节、长度、数据范围]一览表
- linux防火墙开启-关闭
- PHP PSR-3 日志接口规范 (中文版)
- [置顶] Codeforces 70D 动态凸包 (极角排序 or 水平序)
- 一个初学者的辛酸路程-FTP-9
- Linux内核协议栈 NAT性能优化之FAST NAT
- kotlin web开发教程【一】从零搭建kotlin与spring boot开发环境
- 【二分图】洛谷P1640连续攻击游戏
- 31. Next Permutation(中等,搞清楚啥是 next permutation)
- MySQL死锁查询【原创】
- 状态压缩dp小结
- OpenResty 最佳实践 lua与nginx的结合 --引用自https://moonbingbing.gitbooks.io/openresty-best-practices/content/
- Mark 韦氏拼音 邮政式拼音 和汉语拼音
- mac brew 安装 nginx fpm mysql 教程
- 题目1454:Piggy-Bank(完全背包问题)
- (第十周)新NABCD
热门文章
- Linux7 安装python3.5.4
- PB笔记之数据窗口行不能编辑的原因
- Consul作为SpringCloud配置中心
- RuntimeError: Model class users.models.UserProfile doesn&#39;t declare an explicit app_label and isn&#39;t in an application in INSTALLED_APPS.
- VBA While Wend循环
- 【转载】Windows检测到IP地址冲突
- 1+x证书学习日志——css 基本选择符
- js时间格式化和相互转换
- Java 之 缓冲流
- 安装配置nginx之后访问不了nginx的问题