在表達式的左值性中,後綴表達式是比較複雜的一種狀況。後綴表達式有不少種,這裏討論的是E1.E2和E1->E2形式的後綴表達式。函數
4.1 E1.E2形式的後綴表達式指針
若E2爲靜態數據成員或引用數據成員,不管E1的左值性如何,E1.E2的結果都是左值;若E2爲非靜態非引用數據成員,C和C++標準都規定若是E1爲左值,則E1.E2也是左值;當E1爲右值時,從原理上說,右值對象的一部分也應該是一個右值,所以在C中,不管E2的左值性如何,E1.E2皆爲右值;那麼C++中的結果又如何呢?按道理應該瓜熟蒂落也爲右值吧,但使人驚訝的是,C++98和C++2003都沒有對此做出規定!所以在C++98和C++2003中,不管編譯器將這種狀況做爲左值或右值都沒有違反標準。這種狀況顯然是一個漏洞,在C++新標準C++11的制定過程當中,WG21的專家在其Defect Reports中認可了這一點,並在C++11中將結果修正爲一個prvalue(pure rvalue,純右值)。對象
struct A編譯器
{編譯
A( int& i ) : r( i ){}原理
static int k;引用
int &r;數據
int j;static
};return
int A::k = 10;
A foo( int& r ){ A a( r ); return A; }
......
int i = 20;
A a( i );
a.k = 30; //靜態成員,左值
a.r = 40; //引用成員,左值
a.j = 50; //a是左值,因此a.j是左值
foo( i ).k = 60; //靜態成員,左值,雖然foo( i )返回一個右值
foo( i ).r = 70; //引用成員,左值,雖然foo( i )返回一個右值
foo( i ).j = 80; //foo( i ).j左值右值都合法,由於標準沒有規定
E2爲函數成員。若E2爲靜態成員函數,不管E1的左值性如何,結果都爲左值。若E2爲非靜態成員函數,如3.1節所述,因爲非靜態成員函數不是左值,所以不管E1的左值性如何,E1.E2的結果都是右值。
4.2 E1->E2形式的後綴表達式
因爲C中的右值地址沒法得到,所以C中的E1老是指向左值的指針,因此C中的E1->E2後綴表達式的結果老是左值;但C++有很大不一樣,C++中的E1->E2後綴表達式是轉換爲等價形式(*E1).(E2)進行計算的,所以E1->E2的左值性與E1.E2相同。