BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #7380同步于 2008/5/24
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

[求助]函数返回引用的问题

flyaway
2008/5/24镜像同步9 回复
请各位大侠帮忙看一下,谢谢大家! 代码如下: #include<iostream.h> int &square(int); void main() { int s=square(15); cout<<"s="<<s<<endl; } int &square(int i) { return i*i; } 报错是: error C2440: 'return' : cannot convert from 'int' to 'int &' A reference that is not to 'const' cannot be bound to a non-lvalue 为什么把后面部分改成这样就可以拉 int t; int &square(int i) { t=i*i; return t; }
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
windam机器人#1 · 2008/5/24
int &square(int i) { return i*i; } int i是栈上的变量。函数ret之后无效。 t是全局变量,位于数据段里,全局有效。
Kumbayaco机器人#2 · 2008/5/24
提示说的已经很明显了。 i*i是非左值
flyaway机器人#3 · 2008/5/24
【 在 Kumbayaco 的大作中提到: 】 : 提示说的已经很明显了。 i*i是非左值 原来是左值,右值的问题,got it!
hokkien机器人#4 · 2008/5/24
【 在 windam 的大作中提到: 】 : int &square(int i) : { : return i*i; : ................... 其实返回函数内局部变量编译器根本不会管你的,虽然那些空间出了函数会被释放掉,但编译器根本不会管的。也就是说,编译器对于这种类型的失误是不报错的,至少VC这样。 其实楼主这个问题也不是什么左值右值的问题,其实引用就是一种变相指针,只不过你看不到而已,但编译器器确实是用指针来操作引用的。个人以为,i*i 这个运算值不出意外的话应该是放在寄存器当中,比如EAX,而函数返回值确是引用,已经说过了,引用就是一种变相指针,很明显EAX不存在地址,因而返回了引用,当然出错。 呵呵,一家之言,未必正确哦,大家就随便看看吧,这个正确性不敢把握,呵呵
thiefkid007机器人#5 · 2008/5/26
此楼正解 【 在 hokkien 的大作中提到: 】 : 其实返回函数内局部变量编译器根本不会管你的,虽然那些空间出了函数会被释放掉,但编译器根本不会管的。也就是说,编译器对于这种类型的失误是不报错的,至少VC这样。 : 其实楼主这个问题也不是什么左值右值的问题,其实引用就是一种变相指针,只不过你看不到而已,但编译器器确实是用指针来操作引用的。个人以为,i*i 这个运算值不出意外的话应该是放在寄存器当中,比如EAX,而函数返回值确是引用,已经说过了,引用就是一种变相指针,很明显EAX不存在地址,因而返回了引用,当然出错。 : 呵呵,一家之言,未必正确哦,大家就随便看看吧,这个正确性不敢把握,呵呵
Kumbayaco机器人#6 · 2008/5/26
【 在 hokkien 的大作中提到: 】 : 其实返回函数内局部变量编译器根本不会管你的,虽然那些空间出了函数会被释放掉,但编译器根本不会管的。也就是说,编译器对于这种类型的失误是不报错的,至少VC这样。 : 其实楼主这个问题也不是什么左值右值的问题,其实引用就是一种变相指针,只不过你看不到而已,但编译器器确实是用指针来操作引用的。个人以为,i*i 这个运算值不出意外的话应该是放在寄存器当中,比如EAX,而函数返回值确是引用,已经说过了,引用就是一种变相指针,很明显EAX不存在地址,因而返回了引用,当然出错。 : 呵呵,一家之言,未必正确哦,大家就随便看看吧,这个正确性不敢把握,呵呵 分析的很深入也很有道理,不过,取地址不是只能对左值进行的操作么 详见msdn L-Value and R-Value Expressions Expressions that refer to memory locations are called “l-value” expressions. An l-value represents a storage region’s “locator” value, or a “left” value, implying that it can appear on the left of the equal sign (=). L-values are often identifiers. Expressions referring to modifiable locations are called “modifiable l-values.” A modifiable l-value cannot have an array type, an incomplete type, or a type with the const attribute. For structures and unions to be modifiable l-values, they must not have any members with the const attribute. The name of the identifier denotes a storage location, while the value of the variable is the value stored at that location. An identifier is a modifiable l-value if it refers to a memory location and if its type is arithmetic, structure, union, or pointer. For example, if ptr is a pointer to a storage region, then *ptr is a modifiable l-value that designates the storage region to which ptr points. Any of the following C expressions can be l-value expressions: An identifier of integral, floating, pointer, structure, or union type A subscript ([ ]) expression that does not evaluate to an array A member-selection expression (–> or .) A unary-indirection (*) expression that does not refer to an array An l-value expression in parentheses A const object (a nonmodifiable l-value) The term “r-value” is sometimes used to describe the value of an expression and to distinguish it from an l-value. All l-values are r-values but not all r-values are l-values.
vivin机器人#7 · 2008/5/27
i*i的结果是一个临时变量,而临时变量是至少等同于有const修饰的变量的,如果被返回引用,那就意味着可以改变这个临时变量,所以编译器不允许了。 如果只是返回栈上的某个变量,编译器也就给个警告,不会给错误。 【 在 flyaway (flyaway) 的大作中提到: 】 : 请各位大侠帮忙看一下,谢谢大家! : 代码如下: : #include<iostream.h> : ...................
coolxiaoqin机器人#8 · 2008/6/5
【 在 vivin 的大作中提到: 】 : i*i的结果是一个临时变量,而临时变量是至少等同于有const修饰的变量的,如果被返回引用,那就意味着可以改变这个临时变量,所以编译器不允许了。 : 如果只是返回栈上的某个变量,编译器也就给个警告,不会给错误。 讲的没错。函数前面加个const 就可以了
sniffer机器人#9 · 2008/6/5
就是左值右值问题。 临时变量只能由const引用来引用。