C++左值右值

纠正下英文翻译,一直以为是left right value

lvalue:locator value 翻译为左值?可定位的值
rvalue:read value 翻译为右值?可读的值
似乎放在等号左边的叫左值,右边的叫右值?

lvaue是指存储在内存中、有明确存储地址(可寻址)的数据,可以通过变量名访问和改变其值
rvalue指的是可以提供数据值的数据,不一定可以寻址,例如存储于寄存器中的数据

int a = b + c;,a 就是一个左值,可以对a取地址,而b+c 就是一个右值,对表达式b+c 取地址会报错

理解摘抄

理解1

每一个变量都有两个值:

数据值,存储在某个内存地址中。有时这个值也被称为对象的右值,我们也可认为右值的意思是被读取的值read value,文字常量和变量都可被用作右值。

地址值,即存储数据值的那块内存的地址。它有时被称为变量的左值,我们也可认为左值的意思是位置值locator value,文字常量不能被用作左值

理解2

左值:指表达式结束后依然存在的持久对象,可以取地址,具名变量或对象
右值:表达式结束后就不再存在的临时对象,不可以取地址,没有名字

int a = 5;
5 = a; //错误,5 不能为左值,5是右值

纯右值,将亡值

C++11中右值又由两个概念组成:将亡值Expiring value,简称 xvalue和纯右值Pure value,简称 pvalue
每个C++表达式只属于三种基本值类别中的一种:左值 (lvalue)、纯右值 (prvalue)、将亡值 (xvalue)

拥有身份且不可被移动的表达式被称作 左值 (lvalue) 表达式,指持久存在的对象或类型为左值引用类型的返还值。
拥有身份且可被移动的表达式被称作 将亡值 (xvalue) 表达式,一般是指类型为右值引用类型的返还值。
不拥有身份且可被移动的表达式被称作 纯右值 (prvalue) 表达式,也就是指纯粹的临时值(即使指代的对象是持久存在的)。
不拥有身份且不可被移动的表达式无法使用。

纯右值:非引用返回的临时变量( int func() )、运算表达式产生的临时变量(b+c)、原始字面量(2)、lambda表达式等
将亡值:将要被移动的对象、T&&函数返回值、std::move返回值和转换为T&&的类型的转换函数的返回值

左右值引用

引用本身不拥有所绑定对象的内存,只是该对象的一个别名,左值引用就是有名变量的别名,右值引用是不具名变量的别名

C++98/03 标准中就有引用,使用 "&" 表示。但此种引用方式有一个缺陷,即正常情况下只能操作 C++ 中的左值,无法对右值添加引用
int num = 10;
int &b = num; //正确
int &c = 10; //错误

但允许使用常量左值引用操作右值。也就是说,常量左值引用既可以操作左值,也可以操作右值,例如:
int num = 10;
const int &b = num;
const int &c = 10;//右值

右值引用也必须立即进行初始化操作,比如:
int num = 10;
//int && a = num; //右值引用不能初始化为左值
int && a = 10;
int&& val1 = x; //但也有说可以用右值初始化的,既可以绑定左值也可以绑定右值,有空我会试试

和常量左值引用不同的是,右值引用还可以对右值进行修改。例如:
int && a = 10;
a = 100;

std::move()可以把左值引用, 转换为右值引用

std::forward完美转发

当我们将一个右值引用传入函数时,他在实参中有了变量名并持久存在,所以继续往下传或者调用其他函数时,根据C++ 标准的定义,这个参数变成了一个左值
使用forward将参数包一下,传给下一个函数,能保留参数的左右值属性

template<typename T>
void print(T& t){
    cout << "lvalue" << endl;
}
template<typename T>
void print(T&& t){
    cout << "rvalue" << endl;
}

template<typename T>
void Test(T && v){
    print(v);//调用void print(T& t)
    print(std::forward<T>(v));//调用void print(T&& t)
}

这里用forward完美转发,保持v的右值属性,否则直接调用就是识别为左值

这样声明的右值引用,编译器也会将其视为左值
Vector a;//左值
Vector&& b = Vector();//仍是左值,因为有变量名并持久存在

原文链接: https://www.cnblogs.com/lxzbky/p/17064672.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++左值右值

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/399863

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月14日 上午9:36
下一篇 2023年4月14日 上午9:37

相关推荐