【C/C++】C++11 Move, Forward
左值与右值
Lvalue:可以出现在 operator= 左边的
Rvalue:只能出现在operator= 右边的
int a = ;
int a = b;
a = b;
a = a + b;
a + b = a; // error,a + b 是右值 string s1 = "hello";
string s2 = "world";
s1 + s2 = s1; // ok
string() = "world" // ok
注意,虽然 string 等许多容器的临时对象可以被赋值,但编译器见到临时对象会认为它是右值!
int foo() { return ; }
...
int x = foo(); // ok
int y = &foo(); // error
foo() = ; // error
简单地说,能取到地址的(在内存中,而不是在寄存器中)就是右值,其余都是左值。
Rvalue Reference 右值引用
当赋值操作的右边是右值(rvalue),左边的对象不需要特意分配内存去存放这个拷贝(copy),而可以搬移(move)右边对象的资源。
用于解决不必要的拷贝和实现完美转发(perfect forwarding)。
Move Semantics 移动语义
move 相当于 浅拷贝 + 打断原指针,原来的对象无法再使用。

STL 许多地方使用到了右值引用和 move 语义,如 vector 中的 insert() 函数
iterator insert(const_iterator pos, const value_type& x);
iterator insert(const_iterator pos, const value_type&& x) // 接受右值引用
{ return emplace(pos, std::move(x)); } // 将左值变量放到std::move()中,就取得了它的右值引用
Perfect Forwading 完美转发
一个 Unperfect Forwarding 不完美转发的例子
void process(int& i) {
cout << "process(int&): " << i << endl;
}
void process(int&& i) {
cout << "process(int&&): " << i << endl;
}
void forward(int&& i) {
cout << "forward(int&&): " << i << ", ";
process(i);
}
int main() {
int a = ;
process(a); // process(int&): 0
process(); // process(int&&): 1
process(move(a)); // process(int&&): 0
forward(); // forward(int&&): 2, process(int&): 2
// Rvalue经由forward()传给另一个函数却变为Lvalue
// 原因是传递过程中它变成了named object
forward(move(a)); // forward(int&&): 0, process(int&): 0
// forward(a); // error, cannot bind 'int' lvalue to 'int&&'
return ;
}
这时需要使用 std::forward<T>(),保留参数的左/右值特性。
void forward(int&& i) {
cout << "forward(int&&): " << i << ", ";
process(std::forward<int>(i));
}
int main() {
int a = ;
forward(); // forward(int&&): 2, process(int&&): 2
forward(move(a)); // forward(int&&): 0, process(int&&): 0
return ;
}
【C/C++】C++11 Move, Forward的更多相关文章
- 【正则表达式1】C++11正则表达式
https://www.cnblogs.com/pukaifei/p/5546968.html [正则表达式1]C++11正则表达式 头文件 #include <regex> rege ...
- 【读书笔记】2016.11.19 北航 《GDG 谷歌开发者大会》整理
2016.11.19 周六,我们在 北航参加了<GDG 谷歌开发者大会>,在web专场,聆听了谷歌公司的与会专家的技术分享. 中午免费的午餐,下午精美的下午茶,还有精湛的技术,都是我们队谷 ...
- c++11——move/forward
std::move c++11中提供了std::move()来将左值转换为右值,从而方便的使用移动语义.move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝. c ...
- 【编程篇】C++11系列之——临时对象分析
/*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...
- 【机器学习实战】第11章 使用 Apriori 算法进行关联分析
第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...
- 【STM32H7教程】第11章 STM32H7移植SEGGER的硬件异常分析
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第11章 STM32H7移植SEGGER的硬 ...
- 【C/C++】C++11 Lambda
Lambda C++11 中 lambda 是一个匿名函数对象 最简形式 []{ cout << "lambda" << endl; }(); // pri ...
- 【手势交互】9. PS Move
索尼研发体感控制技术已有10年,在过去那么多年里.尝试了3D摄像头.超声波和电磁感应等各种技术.最后还是觉得眼下的MOVE所使用的技术最为合适.PS Move是索尼于2010年9月份推出.用来让PS3 ...
- 【转帖】iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二
iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二 https://www.cnbeta.com/articles/tech/894449.htm 供应链的掌控力很重要 苹果今年 ...
随机推荐
- [NOIP2017普及组]棋盘
题目 题目描述 有一个m × m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的),你只 ...
- POJ滑雪
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 97172 Accepted: 36843 Description ...
- Flask实战-留言板-使用Flask-DebugToolbar调试程序、Flask配置的两种组织形式
使用Flask-DebugToolbar调试程序 扩展Flask-DebugToolbar提供了一系列调试功能,可以用来查看请求的SQL语句.配置选项.资源加载情况等信息.这些信息在开发时会非常有用. ...
- DDL、DML和DCL的区别与理解
DML.DDL.DCL区别 . 总体解释: DML(data manipulation language): 它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令 ...
- 第十六节 BOM基础
打开.关闭窗口 open:蓝色理想运行代码功能 <button onclick="window.open('http://www.baidu.com')">打开窗口&l ...
- Redis学习-主从复制、哨兵
主从复制 官方文档:https://redis.io/topics/replication Redis中的主从复制,也就是Master-Slave模型,有以下特点 Master可以拥有多个slave ...
- MyBatis笔记(二) 最简单的insert命令
接上一篇随笔.这里没有用到MyBatis最关键的映射器接口,因此只做个简单的insert操作,update和delete同理,就不再赘述了. 直接上代码: 首先是dao包下的UserDAO.java文 ...
- Java初始化块
1.使用初始化块 [修饰符]{ //初始化块的可执行性代码 } 初始化块虽然也是Java类的一种成员,但它没有名字,也就没有标识,因此无法通过类.对象来调用初始化块.初始化块只在创建Java对象时隐式 ...
- Oracle 12c 单实例安装
准备工作 实验环境:Redhat 6.6 Oracle 12c 12.2.0.1 1.官网下载 https://www.oracle.com/technetwork/database/enterp ...
- harbor pull 失败
STep1: 显示下面的错误 Error response from daemon: unknown: The image is not signed in Notary Step2: 这儿暂时不要选 ...