前言
左值(lvalue)和右值(rvalue)是 c/c++ 中一个比较晦涩基础的概念,不少写了很久c/c++的人甚至没有听过这个名字,但这个概念到了 c++11 后却变得十分重要,它们是理解 move/forward 等新语义的基础。
左值和右值的定义
关于左值和右值的准确定义,大家一直众说纷纭,很难给这两个名词下一个非常清晰的定义。有一种说法大家的接受度比较高:
lvalue – An object that occupies some identifiable location in memory
rvalue – An object that is not a lvalue
上面的话翻译过来就是:左值是程序中具有可识别物理存储位置的对象,左值是保存在内存中的,而不是寄存器里;所有不是左值的都是右值
让我们举几个例子:
// lvalue example
int i = 0; // i is a lvalue
int *p = &i; // i's address is identifiable
i = 2; // memory content is modified
class dog;
dog d; // lvalue of user defined type(class)
// most variables in C++ code are lvalue
// rvalue example
int x = 2; // 2 is an rvalue
int x = i + 2; // (i+2) is an rvalue
int *p = &(i + 2); // error
i + 2 = 4; // error
2 = i // error
dog d1;
d1 = dog(); // dog() is rvalue of user defined type (class)
int sum(int x, int y) { return x + y; }
int i = sum(3, 4); // sum(3, 4) is an rvalue
通过上面的代码片段,不知道大家有没有发现左值和右值的区别呢?
这里为了方便大家记忆,我简单给大家总结一下:
左值:定义的变量、返回左值引用的函数、赋值、下标、解引用、前置递增/递减运算符这些都是左值
右值:字面常量、返回非引用的函数、算术、关系、位和后置递增/递减运算符这些都是右值