boost::swap
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规则找到全局名字空间的特化交换函数,实现高效的交换。
boost::swap的更多相关文章
- 使用Boost库(1)
如何说服你的公司.组织使用Boost库 one of the most highly regarded and expertly designed C++ library projects in th ...
- boost开发指南
C++确实很复杂,神一样的0x不知道能否使C++变得纯粹和干爽? boost很复杂,感觉某些地方有过度设计和太过于就事论事的嫌疑,对实际开发工作的考虑太过于理想化.学习boost本身就是一个复杂度,有 ...
- boost any库
转: 原理 c++是一个强类型的语言,要实现一个万能类型可以考虑用void*来保存数据,然后用类型转换进行操作,如: class MyAny{ MyAny(void* input):content_( ...
- boost array使用
#include <iostream> #include<boost/array.hpp> int main() { boost::array<int, 6> ar ...
- Boost源码剖析之:泛型指针类any
C++是强类型语言,所有强类型语言对型别的要求都是苛刻的,型别一有不合编译器就会抱怨说不能将某某型别转换为某某型别,当然如果在型别之间提供了转换操作符或是标准所允许的一定程度的隐式转换(如经过非exp ...
- stl 比较和boost LessThanComparable
C++ STL的几种常用“比较”概念简述 在C++的现行标准(C++ 98)中,由于没有类似“接口”这样的东西,我们在泛型编程时往往只能对模板类型作一些假设,要求其符合某个需求清单,也就是属于某个 ...
- boost源码剖析----boost::any
boost源码剖析----boost::any 有的时候我们需要有一个万能类型来进行一些操作,这时候boost::any就派上用场了. boost::Any testInt(10); int val ...
- c++新特性与boost
<Boost程序库探秘——深度解析C++准标准库>之试读 前一阵子还看到一篇文章,说C#要重蹈C++的覆辙,这里说的C++的覆辙是什么呢?是指C++语言过于臃肿的功能特性,导致学习人员的流 ...
- boost.compressed_pair源码剖析
意义 当compressed_pair的某一个模板参数为一个空类的时候将对其进行“空基类优化”,这样可以使得compressed_pair占用的空间比std::pair的更小. 参考如下代码: #in ...
随机推荐
- java当中JDBC当中的transaction例子
[学习笔记] 7.jdbc的transaction例子: import java.sql.*; public class MySQlTransaction1 { public static void ...
- 在CentOS7 安装 Redis数据库
环境说明: 名称 版本 CentOS CentOS Linux release 7.4.1708 (Core) VMware Fusion 专业版 10.1.1 (7520154) SSH Shell ...
- noip2019集训测试赛(二十一)Problem B: 红蓝树
noip2019集训测试赛(二十一)Problem B: 红蓝树 Description 有一棵N个点,顶点标号为1到N的树.N−1条边中的第i条边连接顶点ai和bi.每条边在初始时被染成蓝色.高桥君 ...
- Python爬虫刷回复
最近闲的无聊,就想着去看看爬虫,顺着爬虫顺利的做到了模拟登录.刷帖子等等,这里简要说一下. 使用Python2.7写的爬虫,对某论坛做模拟登陆和刷帖子.回复等等,由于之前是没有接触过爬虫,这次之后感觉 ...
- WUSTOJ 1311: 开心的金明(Java)动态规划-01背包
题目链接:
- 海思HI35xx平台软件开发快速入门之H264解码实例学习
ref :https://blog.csdn.net/wytzsjzly/article/details/82500277 前言 H264视频编码技术诞生于2003年,至今已有十余载,技术相当成熟 ...
- C++开源库大全
标准库 C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Template Library:标准模板库 ...
- axios 内部原理学习记录
前提:一次面试被问到了,axios有什么特点,对比一下ajax.答的很不满意. axios是一个基于Promise的http请求库,可用于浏览器和 Node.可以说是目前最为常用的http库,有必要了 ...
- 使用 rm -rf 删除了工程目录,然后从 pycharm 中找了回来
一次惊险的 rm -rf 操作,以后删东西真的要小心,慢点操作 前两天周 4 周 5,写了两天的 python 代码没有提交,昨天晚上删日志目录,先跨目录查看了下日志目录的列表情况:ll ~/logs ...
- CSS3浏览器私有属性
CSS3的浏览器私有属性前缀是一个浏览器生产商经常使用的一种方式.它暗示该CSS属性或规则尚未成为W3C标准的一部分.因此每种内核的浏览器都只能识别带有自身私有前缀的CSS3属性.我们在书写CSS3代 ...