C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?--- 函数调用表达式和强制转换

房东的猫 提交于 2020-02-29 05:54:08

对于函数调用表达式和强制转换表达式的结果,在C中都属于右值;C++由于增加了引用类型,结果为引用的函数调用表达式和强制转换表达式都属于左值,示例如下:

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

int fun2( void ){ return 10; }

int i = 20;

fun2( ) = 30;                               //A

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

(  int & )10 = 20;                        //C

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

( int & )i = 40;                             //E

( 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,若目标类型为引用,结果为左值,否则为右值。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!