問題を理解する
デストラクターから例外をスローする例外がすでに実行中の場合はどうすればよいかというジレンマが生じます。既存の例外を上書きするか、既存の例外内に新しい例外をネストすることが解決策として考えられますが、std::terminate で終了するのが標準的なアプローチであると決定されました。
ネストされた例外の考慮
C 11 では std::nested_Exception 機能が導入されており、新しい例外の中に古い例外をネストすることで問題に対処できる可能性があります。ただし、このアイデアは実装されませんでした。
実装されない理由
このコンテキストでネストされた例外を使用しない理由の 1 つは、std::nested_Exception が使用方法は非常に限られており、既知の実用的なアプリケーションは完全にアノテーション付きのコール スタックの作成という 1 つだけです。
この例では、例外のネストによってコンテキストを追加し、デバッグ中にエラーを特定する便利な方法がどのように提供されるかを示します。
<code class="cpp">#include <iostream> #include <sstream> #include <exception> void rethrow(const std::string& context, ...) { std::ostringstream ss; ss << context; auto sep = " : "; (void) ((ss << sep << args), sep = ", ", 0)...); try { std::rethrow_exception(std::current_exception()); } catch(const std::invalid_argument& e) { std::throw_with_nested(std::invalid_argument(ss.str())); } catch(const std::logic_error& e) { std::throw_with_nested(std::logic_error(ss.str())); } catch(...) { std::throw_with_nested(std::runtime_error(ss.str())); } } int main() { try { outer("xyz"); outer("abcd"); } catch(std::exception& e) { print_exception(e); } return 0; } void print_exception(const std::exception& e, std::size_t depth = 0) { std::cerr << "exception: " << std::string(depth, ' ') << e.what() << '\n'; try { std::rethrow_if_nested(e); } catch (const std::exception& nested) { print_exception(nested, depth + 1); } }</code>
予想される出力:
exception: outer : abcd exception: inner : abcdabcd exception: really_inner exception: too long
上記の例は例外のネストを示し、この手法がエラーの追跡とコール スタックの理解にどのように役立つかを示しています。
この例ではネストされた例外の有用性にもかかわらず、特定のシナリオでは、std::terminate による終了の容易さと信頼性のために、デストラクター例外のコンテキストでそれらを使用しないという決定が行われた可能性があります。
以上がC では、デストラクターからスローされた例外を処理するためにネストされた例外を使用しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。