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的更多相关文章

  1. 使用Boost库(1)

    如何说服你的公司.组织使用Boost库 one of the most highly regarded and expertly designed C++ library projects in th ...

  2. boost开发指南

    C++确实很复杂,神一样的0x不知道能否使C++变得纯粹和干爽? boost很复杂,感觉某些地方有过度设计和太过于就事论事的嫌疑,对实际开发工作的考虑太过于理想化.学习boost本身就是一个复杂度,有 ...

  3. boost any库

    转: 原理 c++是一个强类型的语言,要实现一个万能类型可以考虑用void*来保存数据,然后用类型转换进行操作,如: class MyAny{ MyAny(void* input):content_( ...

  4. boost array使用

    #include <iostream> #include<boost/array.hpp> int main() { boost::array<int, 6> ar ...

  5. Boost源码剖析之:泛型指针类any

    C++是强类型语言,所有强类型语言对型别的要求都是苛刻的,型别一有不合编译器就会抱怨说不能将某某型别转换为某某型别,当然如果在型别之间提供了转换操作符或是标准所允许的一定程度的隐式转换(如经过非exp ...

  6. stl 比较和boost LessThanComparable

    C++ STL的几种常用“比较”概念简述   在C++的现行标准(C++ 98)中,由于没有类似“接口”这样的东西,我们在泛型编程时往往只能对模板类型作一些假设,要求其符合某个需求清单,也就是属于某个 ...

  7. boost源码剖析----boost::any

    boost源码剖析----boost::any 有的时候我们需要有一个万能类型来进行一些操作,这时候boost::any就派上用场了. boost::Any testInt(10); int val ...

  8. c++新特性与boost

    <Boost程序库探秘——深度解析C++准标准库>之试读 前一阵子还看到一篇文章,说C#要重蹈C++的覆辙,这里说的C++的覆辙是什么呢?是指C++语言过于臃肿的功能特性,导致学习人员的流 ...

  9. boost.compressed_pair源码剖析

    意义 当compressed_pair的某一个模板参数为一个空类的时候将对其进行“空基类优化”,这样可以使得compressed_pair占用的空间比std::pair的更小. 参考如下代码: #in ...

随机推荐

  1. oracle安装内核参数设置

    安装oracle内核参数说明及设置 kernel.shmmax 说明: Linux进程可以分配的单独共享内存段的最大值(byte) 64位的linux操作系统,设置应该大于SGA_MAX_TARGET ...

  2. Mysql 定时备份(mysqldump)

    #!/bin/bash today=`date +%Y-%m-%d` deleday=`date -d '7 day ago' +%Y-%m-%d` path=/home/data/mysqlback ...

  3. MySQL容量规划和性能测试

    性能容量关键指标: 每秒tps,峰值tps 基础数据量,日均增长数据量 最大连接数 内存分配 IOPS 重点关注指标: 业务指标: 每秒并发用户请求.每秒订单数.用户请求响应时长 折算成性能指标: q ...

  4. truncate删除一个分区,测试全局索引是否失效

    目的,有一个清理数据的需求,需要删除历史的一个分区所有记录信息,但是存在主键global索引,如何更好的维护. 如下测试流程一 提前创建好一个已时间created 字段作为分区键的范围分区表 SQL& ...

  5. Hystrix 用法及注解用法

    一.hystrix参数使用方法 通过注解@HystrixCommand的commandProperties去配置,如下就是hystrix命令超时时间命令执行超时时间,为1000ms和执行是不启用超时 ...

  6. Hystrix 熔断器

    Hystrix 是Netflix开源的一个延迟和容错库,用于隔离访问远程服务,防止出现级联失败 一.Hystrix 的定义 二.Hystrix 的原理 在分布式式系统中应用熔断器后,服务调用方可以自己 ...

  7. Python排序算法(六)——归并排序(MERGE-SORT)

    有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10800699.html 一.归并排序(MERG ...

  8. iOS CGContextRef/UIBezierPath(绘图)

    绘图的底层实现方法 注意:在drawRect方法中系统会默认创建一个上下文(C语言类型)在其他方法中不会有这样一个上下文(可以自己测试) @implementation DrawView //注意,在 ...

  9. FreeRTOS config开始的宏

    FreeRTOSConfig.h系统配置文件中可以自定义,FreeRTOS.h中定义默认值 configAPPLICATION_ALLOCATED_HEAP 默认情况下FreeRTOS的堆内存是由编译 ...

  10. Source Insight用法

    快捷键 Symbol: Browse Project Symbols-:F7, Alt+G Relation View Relationship->For Functions->Pefer ...