intのスローとキャッチはどのように機能しますか?


14

このコードで:

int main()
{
    try
    {
        throw -1;
    }
    catch (int& x)
    {
        std::cerr << "We caught an int exception with value: " << x << std::endl;
    }
    std::cout << "Continuing on our merry way." << std::endl;

    return 0;
}

我々は持っています:

/tmp$ ./prorgam.out
Continuing on our merry way
We caught an int exception with value: -1

catchブロックはどのように読み取ら-1int&ますか?非const lvalue参照に値を割り当てることができませんでした。

そして、なぜstd::cout最初のstd::cerrステートメントの前に2番目のステートメントが実行されるのですか?


2
これはあなたが得た正確な出力ですか?We caught an int exception with value: -1行が最初に印刷されなければなりません。
HolyBlackCat

1
@Scheff、申し訳ありませんが、最初の出力はerror streamnotにリダイレクトされstandard streamます。
Ghasem Ramezani


2
@FrançoisAndrieux許可されている理由は、さまざまなセマンティクスが実行されているためです。一般的に、テンポラリでは、どうなるかわからないため、テンポラリへのconst参照のみを許可することにしました。例外を除いて、オブジェクトの存続期間はわかっているため、オブジェクトを変更して、より高いコンテキストに再スローすることができます。これを容易にするために、標準では非const左辺値参照へのバインドが許可されています。
NathanOliver

1
@FrançoisAndrieux throwは、渡されたオブジェクトのコピーを作成(または移動)します。参照はそのコピーにバインドします。コピーが左辺値であるというのは理にかなっています。
HolyBlackCat

回答:


10

[except.throw] / 3のため、これは問題ありません。

例外をスローすると、例外オブジェクトと呼ばれる一時オブジェクトがコピー初期化([dcl.init]、[class.copy.ctor])されます。一時変数を表す左辺値は、一致するハンドラー([except.handle])で宣言された変数を初期化するために使用されます

重点鉱山

ご覧のとおり、これは一時的なものですが、コンパイラはハンドラを初期化するための左辺値として扱います。このため、const参照は必要ありません。


1
しかし、メッセージが表示される順序とは何ですか?
トマーシュザト-モニカを復活させる

8

このthrow参照から:

他の一時オブジェクトとは異なり、catch句のパラメーターを初期化するとき、例外オブジェクトは左辺値引数と見なされるため、左辺値参照によってキャッチされ、変更され、再スローされます。

したがって、「オブジェクト」は一時的なものですが、それでも左辺値であるため、参照によってそれをキャッチできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.