C++
大约 3 分钟
C++
目录
右值引用
C++11参考:
- 《高速上手C++11 14 17.pdf》
- 【C语言中文网】C++11(主要参考)
本篇参考:
概要
C++11 标准对 C++ 语言增添了约 140 个新特性。右值引用是最重要的特性之一
右值引用不难,只不过是一种新的 C++ 语法。真正理解起来有难度的是基于右值引用引申出的 2 种 C++ 编程技巧,分别为移动语义和完美转发
C++左值和右值
概念
- 字面意思上理解,指的是以引用传递(而非值传递)的方式使用 C++ 右值
- 一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式和右值表达式
- 确切的说 C++ 中左值和右值的概念是从 C 语言继承过来的
区别
值得一提的是,左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。
很多人认为它们分别是"left value"、"right value" 的缩写,其实不然。
lvalue 是“loactor value”的缩写,可意为存储在内存中、有明确存储地址(可寻址)的数据。
rvalue 译为 "read value",指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。
区分
- 通常情况下,判断某个表达式是左值还是右值,最常用的有以下 2 种方法(只适用于大部分场景)
- (1) 可位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值
- (2) 有名称的、可以获取到存储地址的表达式即为左值;反之则是右值
int i=0;// i是左值, 0是右值
class A {
public:
int a;
};
A getTemp()
{
return A();
}
A a = getTemp(); // a是左值 getTemp()的返回值是右值(临时变量)
左值引用 / 常量左值引用 / 右值引用
左值引用(普通引用&,C++98/03)
使用
&
表示缺点:正常情况下只能操作 C++ 中的左值,无法对右值添加引用
int num = 10; int &b = num; //正确 int &c = 10; //错误
常量左值引用(C++98/03)
其中
const &
也被称为万能引用
,因为能为左值或右值添加引用缺点:无法对右值进行修改(实现移动语义时需要)
int num = 10; const int &b = num; //正确 const int &c = 10; //正确
右值引用(&&,C++11)
C++标准委员会在选定右值引用符号时,既希望能选用现有 C++ 内部已有的符号,还不能与 C++ 98 /03 标准产生冲突,最终选定了 2 个 '&' 表示右值引用。
和声明左值引用一样,右值引用也必须立即进行初始化操作,且只能使用右值进行初始化
int num = 10; //int && a = num; //错误,右值引用不能初始化为左值 int && a = 10;
和常量左值引用不同的是,右值引用还可以对右值进行修改
int && a = 10; a = 100; cout << a << endl;
支持常量右值引用
const int&& a = 10;//编译器不会报错
补充
其实,C++11 标准中对右值做了更细致的划分,分别称为
- 纯右值(Pure value,简称 pvalue) C++98/03 标准中的右值(本节中已经做了大篇幅的讲解)
- 将亡值(eXpiring value,简称 xvalue )。 右值引用相关的表达式(比如某函数返回的 T && 类型的表达式)
对于纯右值和将亡值,都属于右值,读者知道即可,不必深究
移动语义、完美转发
详见移动构造函数一章