超载<<运算符和递归

发布于 2024-08-23 03:52:47 字数 472 浏览 12 评论 0 原文

我尝试了以下代码:

#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 语句,则不会发生递归。为什么会这样呢?

I tried the following code:

#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;
}

When I compile & run this, it's as expected; an infinite loop. If I remove the cout statement inside the friend function, the recursion doesn't happen. Why is it so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

腹黑女流氓 2024-08-30 03:52:47

优化器确定您所有剩余的活动都没有影响并将其优化掉。
无论是对还是错是另一回事。

特别是:

X x;

创建空对象“x”

cout << x;

调用:

return (os << obj);

正在附加空对象;编译器注意到“os”自上次调用以来没有增长任何内容,并且没有显示任何进一步这样做的承诺(并且没有其他事情发生),因此它决定整个业务是多余的并且可以在此时被截断。

如果您调用

    cout << "hehe";          // comment this and infinite loop is gone

有一些额外的活动,因此优化器不会删除以下调用。

我猜想如果您用任何非空的东西初始化了 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:

X x;

creates empty object "x"

cout << x;

calls:

return (os << obj);

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

    cout << "hehe";          // comment this and infinite loop is gone

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 than cout << "hehe";, you'd have recursion running just the same.

素衣风尘叹 2024-08-30 03:52:47

在这两种情况下(无论是否写“hehe”),Visual Studio 2005 都会给出以下警告:

warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow

在这两种情况下它都会编译并且在这两种情况下都会出现堆栈溢出。

然而,如果没有“呵呵”,堆栈溢出就会更快发生。

In both cases (with and without writing "hehe") Visual Studio 2005 gives the following warning:

warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文