蓝色的博文

To summarize, RVO is a compiler optimization technique, while std::move is just an rvalue cast, which also instructs the compiler that it's eligible to move the object. The price of moving is lower than copying but higher than RVO, so never apply std::move to local objects if they would otherwise be eligible for the RVO.

因此,在能够使用copy elision时,我们不要在return时加std::move()。在copy elision不work时,我们还是要加上std::move()从而调用move constructor而不是调用copy constructor.

博文中比较费解的是最后一个示例,这么写似乎产生了bug。

个人理解:最后一个示例触发了RVO,导致第一次拷贝:栈内变量拷贝至返回值临时变量被省略(两次拷贝参见下文),第二次拷贝:临时变量拷贝至具名变量未省略。而因为变量类型是右值引用,第二次的拷贝变成了移动构造。于是就出现了奇怪的输出。

Copy elision

In general, the C++ standard allows a compiler to perform any optimization, provided the resulting executable exhibits the same observable behaviour as if (i.e. pretending) all the requirements of the standard have been fulfilled. This is commonly referred to as the "as-if rule".[8] The term return value optimization refers to a special clause in the C++ standard that goes even further than the "as-if" rule: an implementation may omit a copy operation resulting from a return statement, even if the copy constructor has side effects.[1]

The following example demonstrates a scenario where the implementation may eliminate one or both of the copies being made, even if the copy constructor has a visible side effect (printing text).[1] The first copy that may be eliminated is the one where a nameless temporary C could be copied into the function f's return value. The second copy that may be eliminated is the copy of the temporary object returned by f to obj.

#include <iostream>struct C {C() {}C(const C&) { std::cout << "A copy was made.\n"; }
};C f() {return C();
}int main() {std::cout << "Hello World!\n";C obj = f();return 0;
}

Depending upon the compiler, and that compiler's settings, the resulting program may display any of the following outputs:

Hello World!
A copy was made.
A copy was made.

Hello World!
A copy was made.

Hello World!

这里有一篇博文,结合了《深度探索C++对象模型》,博文链接。

在g++中开启选项-fno-elide-constructors可以去掉任何返回值优化,则C obj = f(); 中,会发生两次拷贝,f()内栈内变量拷贝构造返回值临时变量,返回值临时变量拷贝构造obj变量。

这里有一份更详细点的文档...

https://en.cppreference.com/w/cpp/language/copy_elision

===============================================================

最后是关于push_back与emplace_back的测试。

T &&var1 = std::move(var2); 不存在移动拷贝。

template< class... Args >
void emplace_back( Args&&... args );通过std::forward<Args>(args)...实现。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct Stu {
 4     int age;
 5     Stu(const int age = 0):age(age) {
 6         cout << "construct" << endl;
 7     }
 8     Stu(const Stu& s){
 9         cout << "copy construct" << endl;
10     }
11     Stu(Stu&& s) {
12         cout << "move construct" << endl;
13     };
14     Stu& operator = (const Stu& s) {
15         cout << "operator construct" << endl;
16     }
17     ~Stu(){
18         cout << "destruct" << endl;
19     }
20 };
21
22 Stu Init(const int age) {
23     return Stu(age);
24 }
25
26 int main() {
27     Stu s1(26);
28     cout << "1--------------" << endl;
29     Stu s2 = Init(20);
30     cout << "2--------------" << endl;
31     vector<Stu> ve;
32     ve.reserve(10);
33     cout << "3--------------" << endl;
34     ve.push_back(s1);
35     cout << "4--------------" << endl;
36     Stu&& ss = std::move(s1);
37     ve.push_back(std::move(s1));
38     cout << "5--------------" << endl;
39     ve.emplace_back(Stu(3));
40     cout << "6--------------" << endl;
41     ve.emplace_back(3);
42     return 0;
43 }
44
45 /*
46 construct
47 1--------------
48 construct
49 move construct
50 destruct
51 move construct
52 destruct
53 2--------------
54 3--------------
55 copy construct
56 4--------------
57 move construct
58 5--------------
59 construct
60 move construct
61 destruct
62 6--------------
63 construct
64 destruct
65 destruct
66 destruct
67 destruct
68 destruct
69 destruct
70 */

View Code

转载于:https://www.cnblogs.com/dirge/p/10389996.html

copy elison RVO NRVO相关推荐

  1. C++中的RVO、NRVO与Copy Elision

    RVO: Return Value Optimization NRVO: Named Return Value Optimization RVO 和 NRVO 自C++98时代就已存在,即当函数按值返 ...

  2. 编译器优化RVO和NRVO

    文章目录 编译器选择 RVO/NRVO 不执行RVO和NRVO优化 只执行RVO优化 只进行NRVO优化 进行RVO和NRVO优化 哪些情况RVO/NRVO优化不执行 参考资料 编译器选择   如果想 ...

  3. Rocksdb Slice使用中的一个小坑

    本文记录一下使用Rocksdb Slice过程中的一个小小坑,差点没一口老血吐出来. rocksdb的Slice 数据结构是一个小型得不可变类string数据结构,设计出来的目的是为了保证rocksd ...

  4. 深入C++面试题总结

    C++基础知识框架: 写在开篇:总结了更为深入的各大厂的C++面试题,干货满满,快收藏起来呀~~ 目录: C++基础知识框架: 1. RAII: 2. 大端和小端: 3. 生成可执行文件过程及各个过程 ...

  5. C++11\14\17\20 新特性整理

    文章目录 C++11 新特性 01 auto 与 decltype 02 defaulted 与 deleted 函数 03 final 与 override 04 尾置返回类型 05 右值引⽤ 06 ...

  6. C++中的CopyElision

    函数返回对象的Copy Elision处理 以前C++函数返回一个对象的时候,涉及到对象的拷贝,为了提高效率,加入了copy elision的优化设计. 假如我们有一个Vector类,表示向量. 在C ...

  7. C++11右值引用、移动语义、完美转发详解

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  8. C++11\14\17\20 特性介绍

    C++11 新特性 #01 auto 与 decltype auto: 对于变量,指定要从其初始化器⾃动推导出其类型.⽰例: auto a = 10; // 自动推导 a 为 int auto b = ...

  9. C++:类的拷贝和移动、初始化和赋值

    C++:类的拷贝和移动.初始化和赋值 测试代码 <C++Primer>学到拷贝控制这一章开始有点犯晕,拷贝和移动的各种使用条件和限制很不好理解.同时,在使用类对象的时候,明显能够感觉到正如 ...

最新文章

  1. 【通俗理解线性代数】 -- 施密特正交化与QR分解
  2. mysql 一键获取数据库表结构
  3. lnmp安装博客系统WordPress
  4. Android toolbar menu 字体点击样式
  5. C#委托及事件 详解(讲得比较透彻)
  6. Python 字符串方法详解
  7. 随笔编号-09 批量导入数据(Mysql)报MySQL server has gone away 问题的解决方法
  8. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第7篇]随机性如何辅助计算和什么是BPP类问题
  9. shell取当前月份第一天_红帽认证8.0版本即将发布!Ansible和shell脚本自动化将重点考察...
  10. 收藏!博士大佬的《机器学习》西瓜书手推笔记!
  11. python3.6网络爬虫_python3.6网络爬虫
  12. Python Tricks(四)—— list of lists 的flatten
  13. 安装Genymotion步骤,启动模拟器时显示CPU不支持虚拟化—解决方法:惠普主机开启VT虚拟化CPU
  14. eNSP教程 —— 物理机如何使用web登录到防火墙
  15. 冒泡排序图解+代码示例
  16. 托福百日冲刺—词汇(14)
  17. 为什么宁愿工资低点,也不建议去外包公司?
  18. 管理活动目录域服务实训_工商管理学院党总支举行校园公益服务活动
  19. Ubuntu18.04安装redmine+mysql+nginx+Passenger
  20. JavaScript中类似java常量constants使用方法

热门文章

  1. ×××S 2008 实用小技巧
  2. ***必备兵器与技能
  3. Jinja2 模板用法
  4. Ubuntu apt安装/卸载软件和设置软件源
  5. C++ 用vector创建数组对象
  6. php接受post值报错,php接收post参数时报错怎么办
  7. YZYZ菜鸟编程小助手
  8. iOS----------苹果警告
  9. CentOS7下安装MySQL5.7安装与配置(转)
  10. html5开发windows8应用 windows8介绍