在c++中左值和右值的概念极易混淆,也最让c++er着急的两个概念,然而,理解它们的不同点是非常重要的。
C++98/03和 0x标准中对lvalue和rvalue都有不同,C++98/03的解释如下:
lvalueness versus rvalueness is a property of expressions, not of objects.
Every expression is either an lvalue or an rvalue.
Lvalues name objects that persist beyond a single expression. For example, obj, *ptr , ptr[index] , and ++x are all lvalues.
Rvalues are temporaries that evaporate at the end of the full-expression in which they live ("at the semicolon"). For example, 1729 , x + y ,std::string("meow") , and x++ are all rvalues.
c++11中解释如下:
A reference type that is declared using & is called an lvalue reference, and a reference type that is declared using && is called an rvalue reference.
C++中每个表达式称为左值表达式或右值表达式,不是左值表达式必定是右值表达式。判断一个表达式是否是左值表达式还是左值表示的一个直觉的
方法就是,把表达式看成一个函数,则函数的返回值为引用形式的为左值表示式。
例子:
1 下标操作符[]的函数形式:T& operator[](T*, ptrdiff_t),因此A[0]是一个左值表达式(A为数组类型)。
2 解引用操作符*的函数形式:T& operator*(T*),因此*p是一个左值表达式(p为指针类型)。
3 求反操作符的函数形式:T operator-(T),因此-x是一个右值表达式。
C++中左值和右值来源于C,原始的意思是根据赋值符号而定,在赋值符号左边的称为左值,在右边称为右值。然而,在现代c++中,左值更多的被
认为是一个可定位值,一个左值指的是一块存储区域,尽管这对于函数来说是不对的,因为函数不是一个对象,相似的,右值被看成是一个表达式的
值。
右值不能用来初始化non-const引用,那是因为,右值不能转化为一个左值,而当程序上下文中需要右值的时候,左值是可以隐式转化为右值的。这一具有约
束力的限制和可转变的class右值性导致了很有趣的结果。
struct A {
A& operator=(const A&) { return *this; }
};
void func(A&);
..
func(A() = A()); // OK, operator=操作符产生左值
ofstream("some") << some_variable; // OK
reference:http://accu.org/index.php/journals/227