【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 供应链的掌控力很重要 苹果今年 ...
随机推荐
- css基础教程
css规则有两个主要部分构成:选择器,以及一条或多条声明. 值的不同写法和单位: 可以使用十六进制设置颜色值:#ff0000; 为节约字节,使用css缩写形式:#f00: 类选择器:以一个点号显示. ...
- Flask-Migrate
终于到了Flask-Migrate,之前在看Flask-SQLAlchemy的时候, Flask支持 makemigration / migrate 吗? 答案在这里该诉你,如果你同时拥有两个三方组件 ...
- Hive中常用的参数配置
-- 查看当前环境参数配置set -v;-- 重置配置为默认值reset; -- 调整map数-- input的文件大小,集群设置的文件块大小,hive中通过set dfs.block.size;命令 ...
- Web前端培训教程:CSS3动画怎么实现的
动画 CSS3属性中有关于制作动画的三个属性: transform,transition,animation keyframes @keyframes mymove{ from{初始状态属性} to{ ...
- dotnetcore ef 调用多个数据库时用户命令执行操作报错
dotnetcore ef 调用多个数据库时用户命令执行操作报错 1.多个DbContext 时报错: 报错: More than one DbContext was found. Specify w ...
- Original Autel MaxiSys Pro MS908P support 2 Year Free Update Online
You can get 2 Year Free Update Online once you place an order on Autel MS908P. Software Version: Eve ...
- 2019 Lonsdor K518S VS K518ISE
2019 Lonsdor K518S VS K518ISE: The same: IMMO capabilities + Vehicle coverage. The difference: The u ...
- 刷Python核心编程第三版的习题时遇到一个findall的坑
在用正则表达式做以下查找时,发现re.findall()对于正则表达式有没有圆括号是有区分的,具体如下 line = 'Tue Sep 18 12:48:21 2029::ilziuv@zcntzir ...
- vue-loader的理解
1.vue-loader是webpack的加载器,允许以单文件组件(SFC)的格式创作Vue组件 2.允许对Vue组件的每个部分使用其他webpack加载器 3.允许.vue文件中的自定义块可以应用自 ...
- Java延时器
package listener; import java.util.Timer; import java.util.TimerTask; public class Timeer { /** * sc ...