7
class foo {
    public:
    friend ostream& operator << (ostream &os, const foo &f);
    foo(int n) : a(n) {}
    private:
    vector <int> a;
};

ostream& operator << (ostream &os, const foo &f) {
    for (int i = 0; i < f.a.size(); ++i)
        os << f.a[i] << " ";
    os << endl; // why is this line a must?
}

int main(void) {
    foo f(2);
    cout << f << endl;
    return 0;
}

上記のコードで、マークされた行が削除されると、セグメント違反エラーが発生します。誰かが理由を説明できますか?

4

1 に答える 1

18
ostream& operator << (ostream &os, const foo &f) {
    for (int i = 0; i < f.a.size(); ++i)
        os << f.a[i] << " ";
    os << endl; // why is this line a must?
}

必須ではありません。あなたが戻っていないため、セグメンテーション違反が発生していますos

ostream& operator << (ostream &os, const foo &f) {
    for (int i = 0; i < f.a.size(); ++i)
        os << f.a[i] << " ";
    return os; // Here
}

ostream を返さない場合の動作は未定義です。があなたのここendlを洗い流してosいます。それが機能しているように見える理由です。

編集:Bo Perssonによると、この場合に機能する理由

os << endl; 「戻り値が期待される場所」(おそらくレジスター)に配置することにより、実際にosを返す別のオペレーター呼び出しです。コードがメインに別のレベルを返すとき、os への参照はまだそこにあります

于 2013-04-03T13:33:04.807 に答える