C/C++左值性精髓(二)哪些表達式是左值,哪些是右值?--- 函數調用表達式和強制轉換

對於函數調用表達式和強制轉換表達式的結果,在C中都屬於右值;C++因爲增長了引用類型,結果爲引用的函數調用表達式和強制轉換表達式都屬於左值,示例以下:函數

int& fun1( int & r ){ return r; }佈局

int fun2( void ){ return 10; }對象

int i = 20;ast

fun2( ) = 30;                               //A變量

cout << ( fun1( i ) = 30 );          //B引用

(  int & )10 = 20;                        //C二進制

( const int & )10 = 20;              //Dstatic

( int & )i = 40;                             //Eco

( double & )i = 50;                     //F浮點數

cout << ( double & )i;               //G

A: fun2的返回值是一個右值,不能做爲內置賦值表達式的左操做數,所以A是錯誤的;

B: fun1返回一個引用,屬於左值,所以能夠做爲內置賦值運算符的左操做數;

C: C試圖將一個右值強制轉換爲引用,可是,只有const引用才能引用一個右值,所以錯  誤;

D: D比C進步了一點,強制轉換爲const引用,但仍然是錯誤的,由於const引用屬於不可修改的左值,不能經過const引用修改其引用的對象;

E: E將一個int變量強制轉換爲int引用並被修改。這個表達式容易出現誤解,覺得i被臨時轉換爲一個引用,其實否則,( int& )i只是產生一個引用到i的臨時引用,i是被引用的對象而非引用自己,被修改的是i的值;

F、G:F和G與E同樣,都產生一個引用到i的臨時引用,但存在兩個問題,一是因爲i的類型與double&所引用的類型不一樣,i的底層佈局從double&的角度看來是double,F中的50先被轉換爲double,再存進i,存進i的內容並不是int格式的50,而是浮點數格式的50,若是此時打印i的值,結果將爲一個「混亂」的整數;二是因爲double和int的二進制寬度不必定相同,若是double寬度大於int,則F和G都將致使未定義行爲。

        對於C++新增的static_cast、reinterpret_cast、const_cast三種強制轉換方式,因爲C++將C風格強制轉換和函數風格強制轉換都轉換爲上述三種方式,所以結果與上述例子相同。而對於dynamic_cast,若目標類型爲引用,結果爲左值,不然爲右值。

相關文章
相關標籤/搜索