5

次のようなコードがある場合:

try {
  doSomething();
} catch (...) {
  noteError();
}

void noteError() {
  try {
    throw;
  } catch (std::exception &err) {
    std::cerr << "Note known error here: " << err.what();
  } catch (...) {
    std::cerr << "Note unknown error here.";
  }
  throw;
}

元の例外は、noteError()の下部フレーム内の両方の場所からスローされますか?

4

2 に答える 2

6

元のコードは問題ありませんでした。さまざまな例外タイプをキャッチし、メッセージをログに記録して再スローする関数を呼び出しました。ステートメントは、対応するブロックthrow内に直接表示する必要はありません。catchただし、これらの「note」関数の1つを呼び出し、現在例外を処理していない場合、プログラムはを呼び出しますterminate()

新しいコードも問題ありません。すべてをキャッチしてから、再スローする別の関数を呼び出して、より具体的なハンドラーに移動することは問題ありません。これは、C++FAQで説明されている例外ディスパッチャのイディオムです。ディスパッチブロックが終了したに例外を再スローするのは少し奇妙に見えますが、現在の場所ではなく、(元のブロック内で)返されthrowた後に同じステートメントが発生した場合、それは完全に正常です。これは、標準の§15.1/6で示されています。noteErrorcatch

于 2010-08-24T22:42:57.163 に答える
4

標準 (§15.1/2) の文言は次のとおりです (強調は私のものです)。

例外がスローされると、制御は一致するタイプ(15.3) を持つ最も近いハンドラーに転送されます。「最も近い」とは、try キーワードに続く複合ステートメント、ctor-initializer、または関数本体が、制御のスレッドによって最後に入力され、まだ終了していないハンドラーを意味します。

try ブロックが「終了」したのはいつですか? 文法 (§15/1) によれば、try ブロックは一連のハンドラーで終了するため、ブロックは最後のハンドラーが終了すると終了します。言い換えると:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

はい、あなたのコードは問題ありません。再スローされると、最も近い try ブロックに一致するハンドラー (つまりcatch (...)) があるため、そのハンドラーに入ります。

于 2010-08-24T23:17:14.657 に答える