Rvalue in C++

Rvalue in C++

lvalue vs rvalue

在C中,判断是左值还是右值比较容易,赋值运算符的左边就是左值,右边就是右值。但在C++中不能这样一概而论。

What is lvalue

左值意味着其地址是可以访问的,即我们可以使用&运算符去访问地址。例如:

1
2
3
4
int x = 1;
int *ptr = &x;

int *ptr2 = &(x+1); //Compiler Error

因为(x+1)在这个表达式之后不能再生效,因此这不是左值而是一个右值。

What is rvalue

非左值即为右值,如下:

1
2
3
4
5
6
7
8
9
10
int *ptr = &(1); //Compiler Error, 1 is rvalue
int *ptr2 = &(x+1); //Compiler Error, x+1 is rvalue

int getData()
{
int data = 0;
return data;
}

int *ptr = &getData(); //Compiler Error

getData()是一个右值,在赋值之后这个临时值就失效了,里面的data是拷贝出来的,因此我们不能取其地址。

Is rvalue immutable in C++

虽然我们不能获取右值的地址,但我们能根据右值的数据类型去修改其。

rvalues of builtin data type is Immutable

我们无法修改内置的数据类型,例如:

1
2
3
4
5
(x+7) = 7;

getData() = 9;

// Both Compile Error

rvalue of User Defined data type is not Immutable

如果右值是用户定义的数据类型,我们可以在同一个表达式中使用成员函数去修改右值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Person {
int mAge;
public:
Person() {
mAge = 10;
}
void incrementAge()
{
mAge = mAge + 1;
}
};


Person getPerson()
{
return Person();
}

getPerson().incrementAge(); // persist in single expression

What is rvalue reference in C++11

lvalue references

在C++11以前只有引用,即指向现存变量的别名。

c++11将原来的引用变成了左值引用,只能引用左值:

1
2
3
int x = 1;
int & lvalueRef = x; // lvalueRef is a lvalue reference
int & lvalueRef2 = (x+1); // compile error

rvalue Reference

右值引用是C++11引入的新特性:

1
2
3
4
5
6
int && rvalueRef = (x+1);

int & lvalueRef3 = getData(); // compile error

const int & lvalueRef3 = getData(); // OK but its const
int && rvalueRef2 = getData();