C++笔记:左值和右值

这两个概念看似简单,其实大部分人很多时候都没有细分他们的差别。最近看到primer书里讨论rvalue reference(右值的引用)时觉得自己应该再回去看看。而事实上左值和右值本身也确实很简单。

这是微软在VS2017中对左右值的定义:https://msdn.microsoft.com/en-us/library/f90831hc.aspx
Every C++ expression is either an lvalue or an rvalue. An lvalue refers to an object that persists beyond a single expression. You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (const) variables, are lvalues. An rvalue is a temporary value that does not persist beyond the expression that uses it. To better understand the difference between lvalues and rvalues, consider the following example:

在《C++ Primer》第五版中,对左右值的说明如下:

Generally speaking, an lvalue expression refers to an object’s identity whereas an rvalue expression refers to an object’s value.

其实早先lvalue就是如字面指“可以用在赋值符号左边的值”,直到ISO C加入了“const”关键字。所以人们发现并不是所有左值都可以被赋值,所以定义了modifiable lvalues。在C99中对modifiable lvalues的定义为:

an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

左值可以随时转化为右值,然而右值一般不可以转变为左值,除了一些特殊情况,例如:解引用*操作符

int arr[] = {1, 2};
int* p = &arr[0];
*(p + 1) = 10;   // OK: p + 1 is an rvalue, but *(p + 1) is an lvalue

在c++标准中对lvalue-to-rvalue conversions的描述为:

An lvalue (3.10) of a non-function, non-array type T can be converted to an rvalue. […] If T is a non-class type, the type of the rvalue is the cv-unqualified version of T. Otherwise, the type of the rvalue is T.

CV-qualifier is a term used to describe const and volatile type qualifiers.

Rvalue References(C++11)

rvalue references(右值引用)用&&表示。它与左值引用&不同,不能互相引用。

int i=42;
int &r=i;               //ok:r refers to i
int &&rr=i;             //error:cannot bind an rvalue reference to an lvalue
int &r2=i*42;           //error:i*42 is an rvalue
const int &r3=i*42;     //ok:we can bind a reference to const to an rvalue
int &&rr2=i*42;          //ok:bind rr2 to the result of the multiplication

对于产生右值的表达式,we can bind either an lvalue reference to const or an rvalue reference to such expressions(怕翻译过来引起误会就引用primer上的原文)。
可以将右值引用继续赋值给一个左值引用而非右值引用,因为这时右值引用本身已经是一个变量,即左值

int &&r=5;
int &&r1=r;     //error
int &r2=r;      //ok
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值