C++ 右值引用与 const 关键字
C++11 新增了另一种引用:右值引用(rvalue reference),这种引用可指向右值,是使用 &&
声明的。使用右值引用可以减少复制操作,延长临时对象生命周期,提升程序性能。它一般被用来实现移动语义和完美转发,将 const
关键字用于右值引用的场景不多,这里来总结一下 const
右值引用的特性,对其是否具有实际应用价值不做讨论。右值引用必须在创建的同时进行初始化,且只能使用右值进行初始化,可将 const
关键字用于右值引用,如下所示:
//声明并初始化常规右值引用变量
int && rrx = 55;
//将const关键字用于右值引用变量,以下几种为等效表示
const int && crrx = 55;
int const && crrx = 55;
在 Microsoft Visual Studio 中连续多个 const
会被编译器解释成一个,即 const const const const int &&
与 const int &&
等效,除此之外,const int const &&
在 Microsoft Visual Studio 中也与 const int &&
等效,而 int && const
在 QT minGW 中将会报错,在 Microsoft Visual Studio 中与 int &&
等效。
常规右值引用与 const
右值引用的特性如下:
- 类型为
int &&
的引用只能用来引用右值,不能用来引用左值,后面可修改其值。可将类型为int
的非左值(比如字面常量100
、多项表达式1+50*2
、函数的int
返回值)、类型不是int
但可转换为int
的非左值(比如多项表达式1.0+50.0*2.0
、字面常量100.0
、函数的double
返回值)在初始化时赋给rrx
。变量初始化完成后,其地址就固定不变,其表现与int
类型变量一致,右值引用变量自身属于左值。 - 类型为
const int &&
的引用也只能用来引用右值,不能用来引用左值,但后面不可修改其值。可将类型为int
的非左值(比如字面常量100
、多项表达式1+50*2
、函数的int
返回值)、类型不是int
但可转换为int
的非左值(比如多项表达式1.0+50.0*2.0
、字面常量100.0
、函数的double
返回值)在初始化时赋给crrx
。变量初始化完成后,其地址就固定不变,其表现与const int
类型变量一致,自身也属于左值。
常规右值引用变量的初始化用法如下:
//初始化方式一:字面常量
int && rrx = 100;
int && rrx = 100.0;
//初始化方式二:多项表达式
int && rrx = 1+50*2;
int && rrx = 1.0+50.0*2.0;
//初始化方式二:函数返回值
int && rrx = abs(10);
int && rrx = sqrt(10.0);
右值引用在部分情况下会生成临时变量(一个典型例子是使用字面常量右值如 100
来初始化右值引用变量),然后将右值引用变量作为该临时变量的别名,这与 const
左值引用十分相似,但与之不同的是:const
左值引用变量初始化完成后其值就无法被修改(权限为只读),右值引用变量初始化完成后其值仍可修改(权限为可读可写)。在另一些情况下,右值引用可以延长已有临时变量的生命周期,减少复制操作的次数(一个典型例子是使用函数返回的类对象来初始化右值引用变量,在关闭编译器优化的情况下可以将本需 2 次的复制操作减少为 1 次)。
被 const
关键字修饰的右值引用变量初始化用法如下,与常规右值引用变量的区别仅在于它们的可修改属性不同。
//初始化方式一:字面常量
const int && crrx = 100;
const int && crrx = 100.0;
//初始化方式二:多项表达式
const int && crrx = 1+50*2;
const int && crrx = 1.0+50.0*2.0;
//初始化方式二:函数返回值
const int && crrx = abs(10);
const int && crrx = sqrt(10.0);
将初始化时 int &&
与 const int &&
可接受的形式列个表,如下,需要注意的是:可以将右值引用变量用于初始化左值引用变量,但不可将左值引用变量用于初始化右值引用变量,因为右值引用变量自身属于左值。
初始化时可接受的形式 | int && 类型 |
const int && 类型 |
---|---|---|
int 变量 |
不可以 | 不可以 |
const int 变量 |
不可以 | 不可以 |
int & 变量 |
不可以 | 不可以 |
const int & 变量 |
不可以 | 不可以 |
int && 变量 |
不可以 | 不可以 |
const int && 变量 |
不可以 | 不可以 |
形如 100 的 int 字面常量 |
可以 | 可以 |
形如 1+50*2 的 int 多项表达式 |
可以 | 可以 |
返回类型为 int 的函数返回值 |
可以 | 可以 |
形如 100.0 可转换为 int 的字面常量 |
可以 | 可以 |
形如 1.0+50.0*2.0 可转换为 int 的多项表达式 |
可以 | 可以 |
C++ 右值引用与 const 关键字的更多相关文章
- c/c++ 右值引用,forward关键字
c++ forward关键字 forward的由来:模板函数中的推导类型,作为另一函数的参数时,不管实参是什么类型,作为另一个参数的实参时,都变成了左值.因为C++里规定函数的形参就是左值,不过调用侧 ...
- c++ 右值引用,move关键字
c++ move关键字 move的由来:在 c++11 以前存在一个有趣的现象:T& 指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可以指向 rv ...
- C++ 左值引用与 const 关键字
左值引用是已定义的变量的别名,其主要用途是用作函数的形参,通过将左值引用变量用作参数,函数将使用原始数据,而不是副本.引用变量必须在声明时同时初始化,可将 const 关键字用于左值引用,如下所示: ...
- C++ 右值引用与一级指针
将右值引用用于一级指针,在初始化时等号右边必须为右值,有以下几种用法: //方式一:引用一级指针,常规用法 int a = 5; int * &&rrpa = &a; //右值 ...
- [转载] C++11中的右值引用
C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...
- C++11中的右值引用
原文出处:http://kuring.me/post/cpp11_right_reference May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移 ...
- c++11之右值引用
本文大部分来自这里,并不是完全着行翻译,如有不明白的地方请参考原文. 在c++中,创建临时对象的开销对程序的影响一直很大,比如以下这个例子: String getName(){ return “Kia ...
- 【C/C++开发】C++11:左值引用VS右值引用
左值引用VS右值引用 左值引用对于一般的C++程序员再熟悉不过,但对于右值引用(C++0X新特性),就稍微有点不知所云 左值VS右值 在定义变量的时候,经常会用到左值和右值,比如:int a = 1; ...
- C++11右值引用和std::move语句实例解析
关键字:C++11,右值引用,rvalue,std::move,VS 2015 OS:Windows 10 右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践 ...
随机推荐
- 用kubeadm简单部署k8s
一.环境准备 1.三台CentOS6.7虚拟机 master:192.168.0.54 注意:主节点最好是2颗cpu,否则在k8s控制平面初始化的时候会报错: node1:192.168.0.68 n ...
- 【定时功能】消息的定时发送-基于RocketMQ
一.功能介绍 要实现一个消息的定时发送功能,也就是让消息可以在某一天某一个时间具体节点进行发送.而我们公司的业务场景是类似短信的业务,而且数量不小,用户会进行号码.消息内容.定时发送时间等信息的提交. ...
- Mybatis的使用(4)
1:解决实体类成员变量和数据库表中字段名称不一致的问题: 方法1:在写sql语句时,给表中的列名起别名,名字和实体类名称一样 方法2:使用resultMap来解决: 例如:实体类中成员变量为id,na ...
- BTDetect用户手册和技术支持
BTDetect用户手册和技术支持 1. 程序主要功能 BTDetect是BT(BioTechnology) Detect 生物科技检测的缩写.本程序将根据用户的回答推断其两大基因类型.以及具体的小分 ...
- 议题征集令 | Apache DolphinScheduler Meetup 2021 来啦,议题征集正式开启!
点击上方 蓝字关注我们 社区的小伙伴们,经过精心筹备,我们很高兴地宣布,Apache DolphinScheduler Meetup 2021 将于 2021 年 11 月 27 日到来! 在 Mee ...
- java学习第七天xml.day18
反射 在java中,反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力. 获取字节码的方式: 使用反射获取构造器 : 内省
- 简单概述 TCP/IP 协议簇
前言 通信协议是计算机之间交换信息所使用的一种公共语言的规范和约定.Internet 的通信协议包含 100 多种相互关联的协议,但是 TCP 和 IP 是其中两个最核心的关键协议,所以把 Inter ...
- 操作系统学习笔记5 | 用户级线程 && 内核级线程
在上一部分中,我们了解到操作系统实现多进程图像需要组织.切换.考虑进程之间的影响,组织就是用PCB的队列实现,用到了一些简单的数据结构知识.而本部分重点就是进程之间的切换. 参考资料: 课程:哈工大操 ...
- 移动/联通APN提升
绝大部分的时候信号满格速度特别慢 解决办法不一定对所有人有效可尝试一下 一般流程手机的设置-移动网络-移动数据-接入点名称(APN)-新建APN 中国移动如下配置 名称:随便写 APN:cmtds m ...
- React报错之Property 'value' does not exist on type EventTarget
正文从这开始~ 总览 当event参数的类型不正确时,会产生"Property 'value' does not exist on type EventTarget"错误.为了解决 ...