0
点赞
收藏
分享

微信扫一扫

【C++grammar】左值、右值和将亡值


目录

  • ​​C++03的左值和右值​​
  • ​​C++11的左值和右值​​
  • ​​将亡值​​


在C++03中就有相关的概念

C++03的左值和右值

通俗的理解:

(1) 能放在等号左边的是lvalue
(2) 只能放在等号右边的是rvalue
(3) lvalue可以作为rvalue使用

对于第三点可以举个例子:
int x ;
x = 6; //x是左值,6是右值
int y ;
y = 6; //y是左值,6是右值
y = x; //x作为右值,所以左值是可以作为右值使用的

C++11对左值和右值做出了更加详细的划分。

C++11的左值和右值

表达值分为泛左值、右值;
泛左值分为左值和将亡值(涉及右值引用)
右值可分为纯右值和将亡值(涉及右值引用)
【C++grammar】左值、右值和将亡值_右值

左值指定了一个函数或者对象(表达式计算得出的结果),它是一个可以取地址的表达式。
也就是说,如果一个函数或者对象可以取地址,那么他就是一个左值。

int lv1{ 42 }; // Object
int main() {

int& lv2{ lv1 }; // Lvalue reference to Object
int* lv3{ &lv1 }; // Pointer to Object
}
int& lv4() { return lv1; } // Function returning Lvalue Reference

左值例子:

(1) 解引用表达式p
(2) 字符串字面量"abc"
(3) 前置自增/自减表达式 ++i / --i
(4) 赋值或复合运算符表达式(x=y或m
=n等)

纯右值是不和对象相关联的值(字面量)或者其求值结果是字面量或者一个匿名的临时对象.
纯右值例子:

(1) 除字符串字面量以外的字面量,比如 32, ‘a’

(2) 返回非引用类型的函数调用 int f() { return 1;}

(3) 后置自增/自减表达式i++/i–

(4) 算术/逻辑/关系表达式(a+b、a&b、a<<b)(a&&b、a||b、~a)(a==b、a>=b、a<b)

(5) 取地址(&x)

如:

72.0f
a–
x为一个整型变量,&x

左值可以当成右值使用

将亡值

将亡值也指定了一个对象,是一个将纯右值转换为右值引用的表达式:
&&这里不是逻辑与运算符,而是右值引用

int&& rvr1{ 22 }; // 右值引用可以引用纯右值

我们先来看什么是左值引用:
a是个左值,b是a的引用,为左值引用。

int a = 1;
int& b = a;

如果a是个常量22,我们对其引用就会出错:
如下:

int& b{22};   //错!非常量左值引用不可引用纯右值

为了解决这个问题,可以使用const 引用(常量左值引用)引用纯右值:
这样就能保证22(纯右值)不会通过b修改,这样b就相当于是22的别名。

const int& b{22};

当然还有另一种引用纯右值的方法就是右值引用了:
通过右值引用可以使纯右值的生存期增加,例如:
int&& rvr1{ 22 }; // 右值引用可以引用纯右值
int rv2 =++rv1;
原本22在执行完第一个语句就会消亡,但是使用右值引用之后,就可以在后面的语句通过调用右值引用,继续使用这个值了。

总例:

int prv(int x) { return 6 * x; } // pure rvalue 

int main() {

const int& lvr5{ 21 }; // 常量左值引用可引用纯右值

int& lvr6{ 22 }; // 错!非常量左值引用不可引用纯右值

int&& rvr1{ 22 }; // 右值引用可以引用纯右值

int& lvr7{ prv(2) }; // 错!非常量左值引用不可引用纯右值

int&& rvr2{ prv(2) }; // 右值引用普通函数返回值

rvr1 = ++rvr2; // 右值引用做左值使用

}


举报

相关推荐

0 条评论