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规则找到全局名字空间的特化交换函数,实现高效的交换。

最新文章

  1. 关于composer安装插件时候提示找不到fxp插件时候的解决办法
  2. 承接Hololens游戏外包
  3. 谷歌联合 Adobe 发布 Noto 字体【免费下载】
  4. Java--继承和super关键字
  5. Mysql数据数据[字节、长度、数据范围]一览表
  6. linux防火墙开启-关闭
  7. PHP PSR-3 日志接口规范 (中文版)
  8. [置顶] Codeforces 70D 动态凸包 (极角排序 or 水平序)
  9. 一个初学者的辛酸路程-FTP-9
  10. Linux内核协议栈 NAT性能优化之FAST NAT
  11. kotlin web开发教程【一】从零搭建kotlin与spring boot开发环境
  12. 【二分图】洛谷P1640连续攻击游戏
  13. 31. Next Permutation(中等,搞清楚啥是 next permutation)
  14. MySQL死锁查询【原创】
  15. 状态压缩dp小结
  16. OpenResty 最佳实践 lua与nginx的结合 --引用自https://moonbingbing.gitbooks.io/openresty-best-practices/content/
  17. Mark 韦氏拼音 邮政式拼音 和汉语拼音
  18. mac brew 安装 nginx fpm mysql 教程
  19. 题目1454:Piggy-Bank(完全背包问题)
  20. (第十周)新NABCD

热门文章

  1. Linux7 安装python3.5.4
  2. PB笔记之数据窗口行不能编辑的原因
  3. Consul作为SpringCloud配置中心
  4. RuntimeError: Model class users.models.UserProfile doesn&#39;t declare an explicit app_label and isn&#39;t in an application in INSTALLED_APPS.
  5. VBA While Wend循环
  6. 【转载】Windows检测到IP地址冲突
  7. 1+x证书学习日志——css 基本选择符
  8. js时间格式化和相互转换
  9. Java 之 缓冲流
  10. 安装配置nginx之后访问不了nginx的问题