左值右值
左值
左值是表示数据的表达式(如变量名或解引用的指针)
特点:可以获取地址,可以对他赋值。
位置:左值可以出现在赋值符号左边,也可以出现在赋值符号右边
右值
右值有:字面常量, 表达式返回值 , 函数返回值(不包含左值引用返回).
特点: 右值不能取地址.
位置:右值可以出现在赋值符号右边 , 不能出现在赋值符号的左边,
int a = 0; //左值
int* p = &a; //
int b = 1;
a + b; //右值
int& ref = a; //左值引用给左值取别名
//int& ret2 = a + b; //左值引用一般不可以给右值取别名,权限放大了(表达式返回的是临时变量,临时变量具有常性)
const int& ret2 = a + b; //加const的左值引用就可以引用右值了.
int&& ret3 = (a + b); //右值引用可以给右值取别名
//int&& ret4 = a; //报错:无法将右值引用绑定到左值
int&& ret4 = move(a); //右值引用可以给move后的左值取别名.
左值引用和右值引用的比较
左值引用只能引用左值(给左值取别名),不能引用右值
const后的左值引用即可引用左值,又可引用右值
右值引用只能引用右值,不能引用左值
右值引用可以引用move后的左值.(move是一个库函数,不需要了解)
使用场景
右值引用解决什么问题?
#include <iostream>
using namespace std;
void func(int& a) //加const虽然可以引用右值,但是区分不了引用的值是左值还是右值
{
cout << "void func(int& a)" << endl;
}
void func(int&& a) //在传参的过程中,可以区分出左值或右值
{
cout << "void func(int&& a)" << endl;
}
//上面两个func可以同时存在,对引用的函数类型可以识别到不同
int main()
{
int a = 0;
int b = 1;
func(a);
func(a + b);
}
运行结果
可以区分出左值还是右值
那区分出来的意义何在?
左值右值的意义
不要轻易地移动左值