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 ...
随机推荐
- (5)Spring Boot web开发 --- Restful CRUD
文章目录 `@RestController` vs `@Controller` 默认访问首页 设置项目名 国际化 登陆 & 拦截 Restful 风格 @RestController vs @ ...
- WUSTOJ 1311: 开心的金明(Java)动态规划-01背包
题目链接:
- WUSTOJ 1298: 操作格子(Java)
题目链接:
- h5开发微信公众号重定向到关注页面没有关注按钮 (微信你个坑)
搜索微信公众号是这样的 微信公众号重定向到关注页面没有关注按钮 如何微信公众号重定向到关注页面没有关注按钮,请看上篇笔记 无解,微信一直在封这种通过链接跳转到公众号关注页面的方法.只有放个二维码提示长 ...
- Luogu5400 CTS2019随机立方体(容斥原理)
考虑容斥,计算至少有k个极大数的概率.不妨设这k个数对应的格子依次为(k,k,k)……(1,1,1).那么某一维坐标<=k的格子会对这些格子是否会成为极大数产生影响.先将这样的所有格子和一个数集 ...
- Dev GridControl 子集合标题
显示效果: 设置: this.gridView3.OptionsView.ShowViewCaption = true; this.gridView3.ViewCaption = "资产明细 ...
- php批量检测并去除BOM头的代码
开发中会遇到BOM头, 导致程序无法执行. 浏览器返回接口如下图: 去除BOM头解决方法:<?phpini_set('memory_limit','1024M'); function check ...
- Verilog HDL
https://wenku.baidu.com/view/9943b7acf524ccbff1218463.html https://hdlbits.01xz.net/wiki/Main_Page h ...
- axios配置及使用(发起请求时带上token)
1.安装 利用npm安装 npm install axios --save 2.引入即可使用 import axios from 'axios' 3.目录 4.各个文件设置: (1)env.js ex ...
- Java 之 字符输出流[writer]
一.字符输出流 java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地. 它定义了字节输出流的基本共性功能方法. void write(int c) ...