一、std::swap

std::swap面对指针(如pImpl写法)时效率低,因此需要重写swap

1.1 如何重写swap

  • 为标准库提供特化版本(全特化)
//pImpl写法的Widget
class WidgetImpl{
public:...void swap(Widget& other){using std::swap;swap(pImpl,other.pImpl);}
private:int a,b,c;std::vector<double> v;...
};class Widget{
public:Widget(const Widget& rhs);Widget& operator=(const Widget& rhs){...*pImpl = *(rhs.pImpl);...}...
private:WidgetImpl* pImpl;
};//全特化标准库swap
namespace std{template <>void swap<Widget>(Widget& a,Widget& b){a.swap(b);}
}

如果希望交换的并非是class而是 class template

  • C++只允许对class templates偏特化,不允许对function templates身上进行偏特化,偏特化一个function template 时,惯常的做法是简单的为它添加一个重载版本
//为函数模版提供重载版本
namespace std{template <typename T>void swap(Widget<T>& a,Widget<T>& b){a.swap(b);}
}
  • std命名空间内可以全特化templates,但是不能添加新的templates(或classes或functions或任何其他东西),因此在class tempalte相同的命名空间中声明swap
namespace WidgetStuff{template<typename T>class Widget{...};...template<typename T>void swap(Widget<T>& a,Widget<T>& b){a.swap(b);}
}
  • C++名称查找法则:1)确保找到global作用域或T所在之命名空间内的任何T专属的swap。如果T是Widget并位于命名空间WidgetStuff内,编译器会使用实参取决之查找规则找出WidgetStuff内的swap。如果没有T专属之swap存在,编译器就会使用std内的swap。
  • non-member版本的swap已经通用,提供std空间内的特化版本是为了防止会有客户使用std::swap修饰限定法。
  • 成员版本的swap不要抛出异常:高效率的swao几乎总是基于内置类型的操作,而内置类型上的操作绝对不会抛出异常

1.2 总结

  • 提供成员版本的swap
  • 提供non-member 版本的swap
  • 如果正在编写一个class(而非class template),提供特化的std::swap

25 考虑写出一个不抛异常的swap相关推荐

  1. 《Effective C++》学习笔记(条款25:考虑写出一个不抛异常的swap函数)

    最近开始看<Effective C++>,为了方便以后回顾,特意做了笔记.若本人对书中的知识点理解有误的话,望请指正!!! swap函数是一个非常经典又有用的函数,除了它本身用来交换两个对 ...

  2. 《Effective C++》item25:考虑写出一个不抛异常的swap函数

    std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _T ...

  3. # 自定义异常类 问题: 请使用代码实现 每一个学生(Student)都有学号,姓名和分数,分数永远不能为负数 如果老师给学生赋值一个负数,抛出一个自定异常

    自定义异常类 问题: 请使用代码实现 每一个学生(Student)都有学号,姓名和分数,分数永远不能为负数 如果老师给学生赋值一个负数,抛出一个自定异常 public class NoScoreExc ...

  4. Java实验7 五、JVM抛出一个OutOfMemoryError的异常

    题目要求 编写一个程序,它能导致JVM抛出一个OutOfMemoryError的异常,然后捕获并处理这个异常. 代码 public class JVM {public static void main ...

  5. C++小游戏扫雷——如何写出一个简易的扫雷

    C++小游戏扫雷--如何写出一个简易的扫雷 其实很简单,但是这段代码不知道是否有BUG,有的话可以提出,谢谢大家. all.h函数库 #include "all.h" using ...

  6. 怎样写出一个较好的高速排序程序

    写出一个较好的高速排序程序 高速排序是经常使用的排序算法之中的一个,但要想写出一个又快又准的使用程序,就不是那么简单了 须要注意的事项 首先要写正确.通常使用递归实现.其递归相当于二叉树展开,因此假设 ...

  7. linux mysql 不稳定_linux,mysql:今天写出一个十分弱智的bug!

    今天写出一个十分弱智的bug,记录一下,提醒自己以后别这种犯错,不怕丢人哈~ 在写一个分页查询记录的sql时,要根据添加的时间逆序分页输出,之前的写法是酱紫: select record.a, y.c ...

  8. 写出一个缓存系统的伪代码001

    /*** 写出一个缓存系统的伪代码*/ public class CacheDemo {private Map<String, Object> map = new HashMap<S ...

  9. 给定一个n节点二叉树,写出一个O(n)时间的非递归的过程,将该树每个结点的关键字输出(算法导论第三版第十章10.4-5)

    给定一个n节点二叉树,写出一个O(n)时间的非递归的过程,将该树每个结点的关键字输出.要求除该树本树的存储空间外只能使用固定量的额外存储空间,且过程中不得修改该树,即使是暂时的修改也不允许. (算法导 ...

最新文章

  1. 普林斯顿中国籍教授:中国学生是怎样被一步步淘汰掉的?
  2. Spring Getting Started (1):构建一个RESTful的web服务
  3. iptables的地址取反操作
  4. Codeforces681D Gifts by the List
  5. C语言不用文件系统读取文件,C语言-基础教程-非缓冲文件系统
  6. 天眼FAST如何发现脉冲星?
  7. 【百度飞浆】目标检测综述
  8. SAP Commerce web service 的扩展
  9. 投票彰显电信合约机诺基亚Lumia 800C受热捧
  10. 重温2 在Activity中使用Menu
  11. python学法用法 自动刷分器_Python selenium模拟手动操作实现无人值守刷积分功能...
  12. 新手向:如何理解OpenGL中着色器,渲染管线,光栅化等概念
  13. js制作带有遮罩弹出层实现登录小窗口
  14. 本地源制作docker镜像
  15. idea 调整缩进快捷键_IDEA 代码格式化,快捷键
  16. mysql ocp考试准备多久_MySQL OCP考试复习系列--开篇:了解MySQL考试
  17. 为什么大部分人,会对南北经济“差距”产生误解?
  18. 梦幻之旅:盘点一生必去的50…
  19. 爬取飞卢小说网的小说
  20. The Servers project is closed(Tomcate )

热门文章

  1. 原Oracle全球副总裁王亚卿任京东商城CTO
  2. 【NVMe2.0b 5】NVM Subsystem
  3. 自考大专和函授大专有什么区别
  4. Redis的Key过期问题处理
  5. ASP.NET Core Caching简介
  6. 目标检测(三):SSD
  7. 工作更需要一个踏实的人
  8. 如何在 Kovan 测试网上开始使用 OpenLeverage
  9. 职场人生(十四):回想2012走过来的路
  10. 生产安全管理解决方案