2

私は最近、C++ の一時変数が完全なレキシカル スコープを持つように昇格されているのを見つけて驚きました。

class Foo {
public:
    Foo() {
        std::cout << "A";
    }
    ~Foo() {
        std::cout << "B";
    }
};

int main(void)
{
    // Prints "ACB", showing the temporary being promoted to having lexical scope.
    const Foo& f = Foo();
    std::cout << "C";
    return 0;
}

参照に一時変数を代入するという疑わしい動作は別として、これは実際には問題なく機能します (VS2010 および G++ v4.1 でテスト済み)。出力はACBであり、一時オブジェクトが字句スコープを持つように昇格され、関数の最後でのみ破棄されることを明確に示しています ( のB後に出力されCます)。


他の一時変数はこのようには動作しません:

int main(void)
{
    // Prints "ACBD", showing that the temporary is destroyed before the next sequence point.
    const int f = ((Foo(), std::cout << "C"), 5);
    std::cout << "D";
    return 0;
}

私のコードコメントによると、これは を出力ACBDし、式全体の評価が終了するまで一時変数が保持されることを示します (なぜCが前に出力されるのかB) が、次のシーケンスポイントの前にまだ破棄されます (なぜBが前に出力されるのかD)。(この動作は、C++ のすべての一時変数が機能すると私が考えていた方法でした。以前の動作には非常に驚きました。)

このようなレキシカルスコープを持つために一時的に昇格することが合法である場合、誰かが説明できますか?

4

1 に答える 1

5

定数の左辺値参照または右辺値参照 (C++11以上) にバインドされているテンポラリの有効期間は、その参照の有効期間まで延長されます。2 番目のケースでは、代入の左側に参照がなく、値があるため、一時オブジェクトの有効期間は延長されません。

C++ 11 標準の 12.2/4 および 12.2/5 を参照してください。

完全な式の終わりとは異なる時点で一時変数が破棄される状況が 2 つあります。最初のコンテキストは、配列の要素を初期化するためにデフォルトのコンストラクターが呼び出されるときです [...]

2 番目のコンテキストは、参照が一時的な にバインドされている場合です。参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、参照の存続期間中存続します: [...]

「例外」に続くのは、このケースに当てはまらない状況です。

于 2013-02-05T14:27:51.100 に答える