C++11的左值引用与右值引用总结
概念
在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的对象,即左值持久,右值短暂
以上的定义来自于C++Primer(5th)第121页和第471页。可能令人困惑,看了接下来的例子就明白了
- int &&rr1 = 42;//正确,字面常量是右值
- int &&rr2 = rr1;//错误,表达式rr1是左值
特性中的应用
decltype关键字
使用关键字decltype的时候,左值和右值有所不同。如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型,例如,假定p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&。另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整型指针的指针。
lambda表达式
lambda表达式是形如auto f = [ ]{ }的函数。
lambda可指定其捕获列表的类型,[&]表示捕获列表采用隐式引用捕获方式lambda函数体中所使用的来自所在函数的实体都采用引用方式使用,[=]表示采用值捕获方式。
- /*f1的sz是隐式值捕获,f2的sz是隐式引用捕获
- auto f1 = [=](const string &s)
- { return s.size() >=sz; }
- auto f2 = [&](const string &s)
- { return s.size() >=sz; }
拷贝控制
移动构造函数使用右值引用的形参
- class Foo
- {
- //移动构造函数
- Foo(Foo&&);
- };
引用折叠和实参推断
第一个例外规则影响右值引用的参数推断如何进行:当我们将一个左值传递给函数的右值引用参数,且此右值引用指向模板类型参数(如T&&),编译器推断模板类型参数为实参的左值引用类型。
- //编译器推断T类型是int&(左值引用),而非int
- template <typename T> void f(T&&);
- int i = 0;
- f(i);
引用折叠:在所有情况下(除了一个例外),引用会折叠成一个普通的左值引用类型。
- 即:对于一个给定类型X
- <ol>
- <li>X& & ,X& && ,X&& &都折叠成类型X&<li>
- <li>类型X&& &&折叠成X&&<li>
- </ol>
注:引用折叠只能应用于间接创建的引用的引用,如类型别名或模板参数。
这两个规则导致了两个重要结果:
如果一个函数参数是一个指向模板类型参数的右值引用(如T&&),则他可以被绑定到一个左值。且
如果实参是一个左值,则推断出的模板实参类型将是一个左值引用,且函数参数将被实例化为一个普通的左值引用参数(T&)
也暗示了:我们可以将任意类型的实参传递给T&&类型的函数参数。
函数重载
- void Foo(const X&);
- void Foo(X&&);
我们知道,非常量可以初始化一个底层const,反过来却不行,所以第一种版本可以接收任何能转换成类型X的任何对象。第二种版本只可以传递非const右值,由于精确匹配规则,传递非const右值时,会调用第二种版本,尽管第一种版本也可以接受。
一般来说,我们不需要为函数操作定义接受一个const X&&或是一个普通的X&参数的版本。当我们希望从实参“窃取‘数据时,通常传递一个右值引用。为了达到这一目的,实参不能使const的。类似的,从一个对象进行拷贝的操作,不应该改变该对象,因此,通常不需要定义一个接受一个普通的X&参数的版本。
C++11的左值引用与右值引用总结的更多相关文章
- c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用
为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...
- C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward
这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...
- c++11 左值引用、右值引用
c++11 左值引用.右值引用 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #i ...
- 左值与右值,左值引用与右值引用(C++11)
右值引用是解决语义支持提出的 这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运 ...
- C++11左值引用和右值引用
转载:https://www.cnblogs.com/golaxy/p/9212897.html C++11的左值引用与右值引用总结 概念 1.&与&& 对于在C++中,大家 ...
- C++11常用特性介绍——左值引用、右值引用
一.左值.右值 1)左值:可以放在赋值号左侧.可以被赋值的值:左值必须要在内存中有实体. 2)右值:必须放在赋值号右侧.取出值赋值给其它变量:右值可以在内存中也可以在CPU寄存器中. 二.引用 引用是 ...
- C++11 左值引用和右值引用与引用折叠和完美转发
1.左值与右值 最感性的认识. 当然,左值也是可以在右边的. 左值是可以被修改的,右值不能. 当然取地址也是. 生存周期一般左值会比右值的长,一般右值都计算时产生的无名临时对象,存在时间比较短. 下面 ...
- 【C/C++开发】C++11:左值引用VS右值引用
左值引用VS右值引用 左值引用对于一般的C++程序员再熟悉不过,但对于右值引用(C++0X新特性),就稍微有点不知所云 左值VS右值 在定义变量的时候,经常会用到左值和右值,比如:int a = 1; ...
- (原创)C++11改进我们的程序之右值引用
本次主要讲c++11中的右值引用,后面还会讲到右值引用如何结合std::move优化我们的程序. c++11增加了一个新的类型,称作右值引用(R-value reference),标记为T & ...
随机推荐
- PAT——1056. 组合数的和
给定N个非0的个位数字,用其中任意2个数字都可以组合成1个2位的数字.要求所有可能组合出来的2位数字的和.例如给定2.5.8,则可以组合出:25.28.52.58.82.85,它们的和为330. 输入 ...
- JNI由浅入深_6_简单对象的应用
1.声明native方法 public class ComplexObject { /** * 返回一个对象数组 * @param val * @return */ public native Per ...
- Reading Meticulous Measurement of Control Packets in SDN
SOSR 17 概要 网络流量中有一部分是用于网络管理,(根据packet process survey,该部分流量属于包转发的slow path部分)由于sdn的数控分离,交换机需要向控制器发送大量 ...
- Flume(1)-概述与组成架构
一. 定义 Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统.Flume基于流式架构,灵活简单. 二. 优点 1. 可以和任意集中式存储进程集成. 2. ...
- pycharm社区版新建django文件不友好操作
一.cmd操作 1.django-admin startproject (新建project名称) 2.在pycharm打开project,运行终端输入:python manage.py starta ...
- 详解 Python3 正则表达式(三)
上一篇:详解 Python3 正则表达式(二) 本文翻译自:https://docs.python.org/3.4/howto/regex.html 博主对此做了一些批注和修改 ^_^ 模块级别的函数 ...
- 微信小程序 request请求封装
在utils文件夹新建文件utils.js,封装代码如下: 小程序升级后内部不自带Promise方法,需外部引入Promise方法 var sendRequest = function (url, ...
- SSM 框架基于ORACLE集成TKMYBATIS 和GENERATOR自动生成代码(Github源码)
基于前一个博客搭建的SSM框架 https://www.cnblogs.com/jiangyuqin/p/9870641.html 源码:https://github.com/JHeaven/ssm- ...
- Java程序设计 第16周 课堂实践 —— 数据库3
Java程序设计 第16周 课堂实践 -- 数据库3 课堂实践任务3 查询world数据库,获得New Jessey州所有城市的总人口数. 代码分析 实现查询数据库需要我们修改MessageDAO.j ...
- 20155220 2016-2017-2 《Java程序设计》第10周学习总结
20155220 2016-2017-2 <Java程序设计>第10周学习总结 教材内容学习总结 计算机网络编程概述 路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控 ...