對於函數調用表達式和強制轉換表達式的結果,在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,若目標類型爲引用,結果爲左值,不然爲右值。