返回信息流请各位大侠帮忙看一下,谢谢大家!
代码如下:
#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;
}
这是一条镜像帖。来源:北邮人论坛 / cpp / #7380同步于 2008/5/24
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[求助]函数返回引用的问题
flyaway
2008/5/24镜像同步9 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
int &square(int i)
{
return i*i;
}
int i是栈上的变量。函数ret之后无效。
t是全局变量,位于数据段里,全局有效。
【 在 windam 的大作中提到: 】
: int &square(int i)
: {
: return i*i;
: ...................
其实返回函数内局部变量编译器根本不会管你的,虽然那些空间出了函数会被释放掉,但编译器根本不会管的。也就是说,编译器对于这种类型的失误是不报错的,至少VC这样。
其实楼主这个问题也不是什么左值右值的问题,其实引用就是一种变相指针,只不过你看不到而已,但编译器器确实是用指针来操作引用的。个人以为,i*i 这个运算值不出意外的话应该是放在寄存器当中,比如EAX,而函数返回值确是引用,已经说过了,引用就是一种变相指针,很明显EAX不存在地址,因而返回了引用,当然出错。
呵呵,一家之言,未必正确哦,大家就随便看看吧,这个正确性不敢把握,呵呵
此楼正解
【 在 hokkien 的大作中提到: 】
: 其实返回函数内局部变量编译器根本不会管你的,虽然那些空间出了函数会被释放掉,但编译器根本不会管的。也就是说,编译器对于这种类型的失误是不报错的,至少VC这样。
: 其实楼主这个问题也不是什么左值右值的问题,其实引用就是一种变相指针,只不过你看不到而已,但编译器器确实是用指针来操作引用的。个人以为,i*i 这个运算值不出意外的话应该是放在寄存器当中,比如EAX,而函数返回值确是引用,已经说过了,引用就是一种变相指针,很明显EAX不存在地址,因而返回了引用,当然出错。
: 呵呵,一家之言,未必正确哦,大家就随便看看吧,这个正确性不敢把握,呵呵
【 在 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.
i*i的结果是一个临时变量,而临时变量是至少等同于有const修饰的变量的,如果被返回引用,那就意味着可以改变这个临时变量,所以编译器不允许了。
如果只是返回栈上的某个变量,编译器也就给个警告,不会给错误。
【 在 flyaway (flyaway) 的大作中提到: 】
: 请各位大侠帮忙看一下,谢谢大家!
: 代码如下:
: #include<iostream.h>
: ...................
【 在 vivin 的大作中提到: 】
: i*i的结果是一个临时变量,而临时变量是至少等同于有const修饰的变量的,如果被返回引用,那就意味着可以改变这个临时变量,所以编译器不允许了。
: 如果只是返回栈上的某个变量,编译器也就给个警告,不会给错误。
讲的没错。函数前面加个const 就可以了