左值与右值

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. 中文编码错误,Error output could not be translated from the native locale to UTF-8.

    假如使用http访问仓库,用户配置的pre-commit钩子里面如果有中文,可能会出现"Error output could not be translated from the nativ ...

  2. drools kie-server和kie-workbench安装手册

    Drools规则引擎可以直接在项目中编写drl文件,后调用. 也可以搭建kie-server和kie-workbench来进行远程调用. 关系: 在kie-workbench通过页面配置规则,发布到执 ...

  3. vue:vuex中mapState、mapGetters、mapActions辅助函数及Module的使用

    一.普通store中使用mapState.mapGetters辅助函数: 在src目录下建立store文件夹: ​ index.js如下: import Vue from 'vue'; import ...

  4. zabbix_agentd重装后启动时IPC和共享内存段问题

    zabbix_agentd不知为啥被干掉后重装了zabbix,zabbix用户组id也变了. 重装zabbix后导致zabbix_agentd无法启动,两个问题 问题1: zabbix_agentd ...

  5. AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

    现在AOP的场景越来越多,所以我们有必要理解下和AOP相关的一些概念和机制. import org.aspectj.lang.reflect.SourceLocation; public interf ...

  6. linux常用英文单词记录

    1.skip 跳过忽略 2.next 下一步3.hostname 主机名4.password 密码5.complete 完成6.network 网络7.conf config configuratio ...

  7. 在vim下打开终端

    注意:仅在vim8.1下可用 使用方法: :term 打开默认的终端 如果是linux,或者使用wsl, :term bash Ctrl+W/Ctrl+N 将终端设置成normal模式

  8. allure --version 异常io.airlift.airline.ParseArgumentsUnexpectedException: Found unexpected parameter

    执行allure --version时,有时会出现如下异常: io.airlift.airline.ParseArgumentsUnexpectedException: Found unexpecte ...

  9. asp.net 根据连接地址保存文件,图片

    第一种方式  下载图片,文件 WebClient my = new WebClient(); string url = "http://localhost:1015/resource/loa ...

  10. line-height的高度机理

    1.元素高度从何而来?是由里面的文字撑开的? <!DOCTYPE html> <html lang="en"> <head> <meta ...