C/C++左值性精髓(二)哪些表達式是左值,哪些是右值?----後綴表達式

在表達式的左值性中,後綴表達式是比較複雜的一種狀況。後綴表達式有不少種,這裏討論的是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相同。

相關文章
相關標籤/搜索