最近在实现一个Delegate类的时候碰到了一个问题,就是copy and swap技巧和移动赋值操作符有冲突。
比如有以下一个类:

class Fun
{
public:
Fun(const Fun& rhs) throw(); Fun& operator=(Fun fun)
{
swap(fun);
return *this;
} void swap(Fun& other) throw();
};

这个类实现了copy and swap技巧,在赋值的时候表现的很好。但是如果再加入移动赋值操作符,编译器就不认了:

class Fun
{
//...
Fun& operator=(Fun fun)
{
swap(fun);
return *this;
} Fun& operator=(Fun&& fun)
{
swap(fun);
return *this;
}
//...
}; Fun f;
f = Fun(); //报错

当你调用赋值操作符时,编译器会提示有两个赋值操作符,不知道该调用哪一个!
移动赋值操作符的引入就是为了优化用右值赋值的情况,而copy and swap本身就运用了处理右值情况的技巧,所以在这里会出现冲突。因此如果使用了copy and swap技巧,那么移动赋值操作符就可以省略了,下面是copy and swap技巧的C++11写法:

class Fun
{
public:
Fun(const Fun& rhs) throw(); Fun(Fun&& rhs) throw()
//记得数据初始化
{
swap(rhs);
} Fun& operator=(Fun rhs)
{
swap(rhs);
return *this;
} void swap(Fun& other) throw();
};

不过如果数据结构比较复杂,不适合用copy and swap技巧,那么就需要显式的定义左值赋值操作符和右值赋值操作符了:

class Fun
{
//...
Fun& operator=(const Fun& fun); //左值赋值操作符
Fun& operator=(Fun&& fun); //右值赋值操作符
//...
};

参考文献:http://stackoverflow.com/questions/19841626/move-assignment-incompatable-with-standard-copy-and-swap

copy and swap技巧与移动赋值操作符的更多相关文章

  1. C++ 之 重载赋值操作符

    Widget 类中,定义了一个 Bitmap 类型的私有数据成员 -- pb 指针 class Bitmap { ... }; class Widget { private: Bitmap *pb; ...

  2. C++异常安全、copy and swap

    异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码.(异常中立,就是指任何底层的异常都会抛出到上层,也就相当于是异 ...

  3. C++重载赋值操作符

    1.C++中重载赋值操作函数应该返回什么? 类重载赋值操作符一般都是作为成员函数而存在的,那函数应该返回什么类型呢?参考内置类型的赋值操作,例如 int x,y,z; x=y=z=15; 赋值行为相当 ...

  4. 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    转自 http://www.jb51.net/article/37527.htm,感谢作者 #include "stdafx.h"      #include <iostre ...

  5. C++中复制构造函数与重载赋值操作符总结

    前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...

  6. C++中复制构造函数与重载赋值操作符

    我们都知道,在C++中建立一个类,这个类中肯定会包括构造函数.析构函数.复制构造函数和重载赋值操作:即使在你没有明确定义的情况下,编译器也会给你生成这样的四个函数.例如以下类:   class CTe ...

  7. C++中复制构造函数和赋值操作符

    先看一个例子: 定义了一个类:

  8. 赋值操作符、复制构造函数、析构函数、static成员练习

    /** * 定义一个Employee类,包含雇员名字和一个唯一的雇员标识,为该类定义默认构造函数和参数为表示 * 雇员名字的string构造函数.如果该类需要复制构造函数或赋值操作符,实现这些函数 * ...

  9. [C++]复制构造函数、赋值操作符与隐式类类型转换

    问题:现有类A定义如下: class A{public:        A(int a)                            //构造函数        {              ...

随机推荐

  1. UE4 中的 C++ 与 蓝图交互

    1.Unreal 引擎提供了两种创建新 Gameplay 元素的方法:C++ 和 蓝图视觉脚本. 通过 C++,程序员构建基础游戏系统:设计师可以基于此系统为场景 / 游戏创建自定义的游戏玩法. 这种 ...

  2. (转载)window安装mysql

    一.MYSQL的安装 1.打开下载的mysql安装文件mysql-5.5.27-win32.zip,双击解压缩,运行“setup.exe”. 2.选择安装类型,有“Typical(默认)”.“Comp ...

  3. 学习Java第四周

    复习数组,数组和方法在内存中是怎样存储这个问题,有些一知半解. 复习了面向对象思想,是面向对象思想,类的定义,对象实例化,构造函数,还有用javabean的格式定义类.面向过程是自己解决问题,面向对象 ...

  4. python代码规范以及函数注释规范

    摘要 本文给出主Python版本标准库的编码约定.CPython的C代码风格参见​PEP7.本文和​PEP 257 文档字符串标准改编自Guido最初的<Python Style Guide&g ...

  5. docker 挂载目录挂载不上**

    最近做项目做一个shared Dynamodb, 使用docker挂载一个image,发现怎么都挂载不上, 使用 $ pwd E:\Work\Aws\git\schema\dynamodb\local ...

  6. 仿快播APP源码

    目录 仿快播系统 一.项目总结三步走 二.项目需求分析 三.搭建框架 四.ORM框架分析 五.功能分析 六.项目开发--仿快播视频 服务端client start.py ---- 启动文件 conf ...

  7. 第二阶段:4.产品功能需求文档PRD:7.案例总结

     Dev就是一些开发 这就是一个评价表格 每次沟通都要记得记录以及总结反思

  8. 利用OGG进行数据库表的初始化

    OGG初始化 1.停止目标端re1进程 2.配置ei进程(若目标端有ei进程之前投递的文件则先清空) GGSCI (localhost) 1>add extract ei1, sourceist ...

  9. vue学习笔记(三)class和style绑定

    前言 通过上一章的学习vue学习笔记(二)vue的生命周期和钩子函数,我们已经更近一步的知道了关于vue的一些知识,本篇博客将进一步探讨vue其它方面的内容,vue中关于class和style绑定,关 ...

  10. IDEA环境使用Git

    推送到Github 在设置中登录github账户 点击OK 将项目交给Git管理 之后项目文件就会变成红色 添加文件到暂存区 点击Add之后,项目文件会变成绿色 添加文件到本地仓库 点击Commit ...