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将要加入的最重大语言特性之一.从实践 ...
随机推荐
- 搭建一个完整的K8S集群-------基于CentOS 8系统
创建三个centos节点: 192.168.5.141 k8s-master 192.168.5.142 k8s-nnode1 192.168.5.143 k8s-nnode2 查看centos系统版 ...
- SQL审核工具自荐Owls
关键词: sql审批.sql检测.sql执行.备份 概要 这里主要是向大家推荐一款sql检测.审批工具Owls,用于自动检测.审批sql的执行,还有其他的审批.备份.查询等功能.以提高sql的规范化, ...
- MYSQL常见可优化场景
1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null 可以在num上设置 ...
- 使用Python3将word文档和pdf电子书进行格式互转(兼容Windows/Linux)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_96 一些重要文档格式之间的互转在目前显得尤为重要,pdf作为通用格式在现在各个平台上兼容性是最好的,所以写python脚本将这些w ...
- 举重若轻流水行云,前端纯CSS3实现质感非凡的图片Logo鼠标悬停(hover)光泽一闪而过的光影特效
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_197 喜欢看电影的朋友肯定会注意到一个有趣的细节,就是电影出品方一定会在片头的Logo环节做一个小特效:暗影流动之间光泽一闪而过, ...
- 业务可视化-让你的流程图"Run"起来(6.定时任务&Spring-Batch的集成)
前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(5.SpringBoot集成&微服务编排)]的支持. 分享一下近期我对这个项目的一些改进. 在项目 ...
- java-分支重载以及构造方法
1:方法的签名: 方法名+参数列表就是一个方法的签名 2.方法的重载(Overload): 1)发生在同一个类中,方法名称相同,参数列表不同 2)编译器在编译时会根据方法的签名自动绑定方法 3.构造方 ...
- 什么是云计算?云计算三种模式Sass、Paas、Iaas
云计算 云计算的"云"指的是计算机网络(一般指的是 Internet),"计算"指的是多个计算机共同计算巨大的数据的过程.通过云计算平台把任务分解成一个个小的任 ...
- True 和 False 分别代表数字中的几?形象地记忆
True 和 False 作为布尔值分别代表的意思是真和假. 灯泡亮起就是 1,灯泡熄灭就是 0.0 就是无状态,所以可以代表灯泡熄灭的状态,而 1 就是有状态的,所以可以代表灯泡亮起的状态. 那么, ...
- linux centos7开启防火墙端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload