左值与右值

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. 【正则表达式1】C++11正则表达式

    https://www.cnblogs.com/pukaifei/p/5546968.html [正则表达式1]C++11正则表达式   头文件 #include <regex> rege ...

  2. 【读书笔记】2016.11.19 北航 《GDG 谷歌开发者大会》整理

    2016.11.19 周六,我们在 北航参加了<GDG 谷歌开发者大会>,在web专场,聆听了谷歌公司的与会专家的技术分享. 中午免费的午餐,下午精美的下午茶,还有精湛的技术,都是我们队谷 ...

  3. c++11——move/forward

    std::move c++11中提供了std::move()来将左值转换为右值,从而方便的使用移动语义.move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝.     c ...

  4. 【编程篇】C++11系列之——临时对象分析

    /*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...

  5. 【机器学习实战】第11章 使用 Apriori 算法进行关联分析

    第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...

  6. 【STM32H7教程】第11章 STM32H7移植SEGGER的硬件异常分析

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第11章       STM32H7移植SEGGER的硬 ...

  7. 【C/C++】C++11 Lambda

    Lambda C++11 中 lambda 是一个匿名函数对象 最简形式 []{ cout << "lambda" << endl; }(); // pri ...

  8. 【手势交互】9. PS Move

    索尼研发体感控制技术已有10年,在过去那么多年里.尝试了3D摄像头.超声波和电磁感应等各种技术.最后还是觉得眼下的MOVE所使用的技术最为合适.PS Move是索尼于2010年9月份推出.用来让PS3 ...

  9. 【转帖】iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二

    iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二 https://www.cnbeta.com/articles/tech/894449.htm 供应链的掌控力很重要 苹果今年 ...

随机推荐

  1. nginx 阻止非自己域名解析到服务器

    server模块加入 default_server server { listen 80 default_server; return 403; # return 301 https://$serve ...

  2. flask实战-留言板-Web程序开发流程

    Web程序开发流程 在实际的开发中,一个Web程序的开发过程要设计多个角色,比如客户(提出需求).项目经理(决定需求的实现方式).开发者(实现需求)等,在这里我们假设自己是一个人全职开发.一般来说一个 ...

  3. 用Springboot实现文件下载功能

    ApiOperation(value = "下载文件", httpMethod = "GET", notes = "downloadFile" ...

  4. jQuery的deferred对象使用详解

    转自: https://www.cnblogs.com/PengLee/p/5657101.html jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本.每个版本都会引入一些新功能. ...

  5. 【python】文件处理行与行之间的内容

    在处理文本文件时,很多时候需要我们处理跨行的数据,但是用for循环处理不是很方便,想了一个歪招来处理不是很大的数据. 核心思想就是将上一行的东西存在一个列表里,到下一行用完这个数据在循环体里将列表初始 ...

  6. react-native 导航器 react-navigation 3.x 使用

    React-navigation 介绍 React Navigation 源于 React Native 社区对一个可扩展且易于使用的导航解决方案的需求,它完全使用 JavaScript 编写. (如 ...

  7. python numpy科学计算和数据分析的基础包

    import numpy as np #创建ndarray# data1 = [6, 5, 7, 1, 3]# arrl = np.array(data1)# print(arrl)#多维列表创建nd ...

  8. 软件包管理(rpm,yum)

    软件包管理相关软件: 软件包管理器的核心功能: .制作软件包 .安装,卸载,升级,查询,效验 Redhat ,SUSE : RPM Debian :dpt 依赖关系; 前端工具;yum ,apt-ge ...

  9. eclipse juint4 出错!!!

    今天在学习javaee,调用方法的时候突然出现这个错误,之前还好使,调用了几次就不好使了,我查了很多问题,据说是harmcrest的jar包没有导进来,或者是junit的jar包版本太低了,我过段时间 ...

  10. volatility内存取证

    最近参加了45届世界技能大赛的山东选拔赛,样题里有一个题如下: 师傅好不容易拿到了压缩包的密码,刚准备输入,电脑蓝屏 了... = =",题意简单明了,易于理解.一看就是内存取证的题并且已经 ...