超载<<运算符和递归
我尝试了以下代码:
#include <iostream>
using std::cout;
using std::ostream;
class X
{
public:
friend ostream& operator<<(ostream &os, const X& obj)
{
cout << "hehe"; // comment this and infinite loop is gone
return (os << obj);
}
};
int main()
{
X x;
cout << x;
return 0;
}
当我编译时运行这个,正如预期的那样;无限循环。如果我删除友元函数内的 cout
语句,则不会发生递归。为什么会这样呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
优化器确定您所有剩余的活动都没有影响并将其优化掉。
无论是对还是错是另一回事。
特别是:
创建空对象“x”
调用:
正在附加空对象;编译器注意到“os”自上次调用以来没有增长任何内容,并且没有显示任何进一步这样做的承诺(并且没有其他事情发生),因此它决定整个业务是多余的并且可以在此时被截断。
如果您调用
有一些额外的活动,因此优化器不会删除以下调用。
我猜想如果您用任何非空的东西初始化了 x ,或者执行了除 cout << 之外的任何非空活动。 “hehe”;,你会以同样的方式运行递归。
Optimizer decides all your remaining activity has no effect and optimizes it away.
Whether it's right or wrong is a different matter.
In particular:
creates empty object "x"
calls:
which is appending empty object; the compiler notices 'os' hasn't grown any since the last call and shows no promise doing so any further (and nothing else happens) so it decides the whole business is redundant and can be truncated at this point.
In case you call
there is some extra activity so the optimizer doesn't remove the following call.
I guess if you initialized
x
with anything non-empty, or performed any non-null activity other thancout << "hehe";
, you'd have recursion running just the same.在这两种情况下(无论是否写“hehe”),Visual Studio 2005 都会给出以下警告:
在这两种情况下它都会编译并且在这两种情况下都会出现堆栈溢出。
然而,如果没有“呵呵”,堆栈溢出就会更快发生。
In both cases (with and without writing "hehe") Visual Studio 2005 gives the following warning:
In both cases it compiles and in both cases it gives a stack overflow.
However, without the "hehe" the stack overflow occurs a bit sooner.