オーバーロード<<演算子と再帰
-
23-09-2019 - |
質問
私は、次のコードを試してみました
#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
文を削除した場合、再帰は発生しません。なぜそれはそうでしょうか?
解決
オプティマイザは、すべての残りの活動は効果がありませんし、それを離れて最適化を決定します。 それが正しいか間違っているかどうかは別の問題である。
具体的には、
X x;
作成し、空のオブジェクト "X"
cout << x;
呼び出します:
return (os << obj);
空のオブジェクトを付加された。コンパイラの通知「OS」は最後の呼び出しやショー以来、それは全体のビジネスを決定するように、任意の更なる(他と何も起こりません)ので、やって何の約束をいずれも成長していないしていない冗長であり、この時点で切り捨てることができます。
ここであなたを呼び出す
cout << "hehe"; // comment this and infinite loop is gone
オプティマイザは、次の呼び出しを削除しないように、いくつかの余分な活動がある。
私はあなたが何も空でないとx
を初期化、またはcout << "hehe";
以外の任意のnull以外の活動を行っている場合、あなただけの同じ実行中の再帰を持っているだろうと思います。
他のヒント
ドキュメントVisual Studio 2005 Visualどちらの場合も、
(とと記述することなく、 "笑")は、次のような警告を与えます:
warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow
の両方の場合において、それがコンパイルされ、両方のケースでは、スタックオーバーフローを与える。
しかし、「笑」スタックオーバーフロービット早く起こることはない。
所属していません StackOverflow