std::uncaught_exception、std::uncaught_exceptions
From cppreference.com
| ヘッダー <exception> で定義 |
||
| (1) | ||
| bool uncaught_exception() throw(); |
(C++11まで) | |
| bool uncaught_exception() noexcept; |
(C++11以降) (C++17で非推奨) (C++20で削除) |
|
int uncaught_exceptions() noexcept; |
(2) | (C++17以降) (C++26 以降 constexpr) |
1) 現在のスレッドにライブな例外オブジェクトが存在するかどうかを検出します。つまり、例外がスローされたか再スローされ、まだ対応するcatch句、
std::terminate、またはstd::unexpectedに入っていない状態です。言い換えると、std::uncaught_exceptionは、スタックの巻き戻しが現在進行中であるかを検出します。2) 現在のスレッドでスローされたか再スローされ、まだ対応するcatch句に入っていない例外の数を検出します。
例外がstd::uncaught_exception() = true(C++17まで) std::uncaught_exceptions() > 0(C++17以降)ときに安全に例外をスローできる場合があります。たとえば、スタックの巻き戻しによってオブジェクトが破棄される場合、そのオブジェクトのデストラクタは、デストラクタを抜ける前に例外が何らかのcatchブロックによってキャッチされる限り、例外をスローするコードを実行できます。
目次 |
[edit] パラメータ
(なし)
[edit] 戻り値
1) このスレッドでスタックの巻き戻しが現在進行中の場合は
true、そうでない場合はfalse。2) 現在のスレッドにおける未キャッチの例外オブジェクトの数。
[edit] 注意
整数を返すuncaught_exceptionsが使用される例は、boost.logライブラリです。式BOOST_LOG(logger) << foo();は、まずガードオブジェクトを作成し、そのコンストラクタで未キャッチの例外の数を記録します。出力は、foo()が例外をスローしない限り(この場合、デストラクタでの未キャッチの例外の数は、コンストラクタが観測したものより大きくなります)、ガードオブジェクトのデストラクタによって実行されます。
std::experimental::scope_fail および std::experimental::scope_success (LFTS v3) はuncaught_exceptionsの機能に依存しています。これは、それらのデストラクタがスタックの巻き戻し中に呼び出されたかどうかに依存する異なる処理を行う必要があるためです。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_uncaught_exceptions |
201411L |
(C++17) | std::uncaught_exceptions
|
__cpp_lib_constexpr_exceptions |
202411L |
(C++26) | constexpr for exception types |
[edit] 例
このコードを実行
#include <exception> #include <iostream> #include <stdexcept> struct Foo { char id{'?'}; int count = std::uncaught_exceptions(); ~Foo() { count == std::uncaught_exceptions() ? std::cout << id << ".~Foo() called normally\n" : std::cout << id << ".~Foo() called during stack unwinding\n"; } }; int main() { Foo f{'f'}; try { Foo g{'g'}; std::cout << "Exception thrown\n"; throw std::runtime_error("test exception"); } catch (const std::exception& e) { std::cout << "Exception caught: " << e.what() << '\n'; } }
実行結果の例
Exception thrown g.~Foo() called during stack unwinding Exception caught: test exception f.~Foo() called normally
[edit] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 70 | C++98 | uncaught_exception() の例外仕様が欠落していた |
throw() として指定された |
[edit] 関連項目
| 例外処理が失敗した際に呼び出される関数 (関数) | |
| (C++11) |
例外オブジェクトを扱うための共有ポインタ型 (typedef) |
| (C++11) |
現在の例外を std::exception_ptr にキャプチャする (関数) |
[edit] 外部リンク
| 1. | GOTW issue 47: Uncaught Exceptions |
| 2. | std::uncaught_exceptions のための理由 (N4125) |