在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