std::experimental:: scope_success
|
ヘッダーで定義
<experimental/scope>
|
||
|
template
<
class
EF
>
class scope_success ; |
(ライブラリ基盤 TS v3) | |
クラステンプレート
scope_success
は、スコープが正常に終了した際に終了関数を呼び出すことを目的とした汎用スコープガードです。
scope_success
は
CopyConstructible
、
CopyAssignable
または
MoveAssignable
ではありません。ただし、
EF
が特定の要件を満たす場合、
MoveConstructible
になる可能性があり、これにより
scope_success
を別のオブジェクトでラップすることが可能になります。
A
scope_success
は、破棄時に終了関数を呼び出すアクティブ状態、または破棄時に何もしない非アクティブ状態のいずれかになります。
scope_success
は終了関数から構築された後、アクティブ状態になります。
scope_success
は、手動で、または自動的に(ムーブコンストラクタによって)その
release()
を呼び出すことで非アクティブになります。非アクティブな
scope_success
は、別の非アクティブな
scope_success
で初期化することによっても取得できます。
scope_success
が一度非アクティブになると、再度アクティブにすることはできません。
A
scope_success
は事実上、1つの
EF
と、それがアクティブかどうかを示す
bool
フラグ、さらにスタックアンワインド中にデストラクタが呼び出されたかどうかを検出するために使用される未捕捉例外のカウンタを保持します。
目次 |
テンプレートパラメータ
| EF | - | 格納される終了関数の型 |
| 型要件 | ||
-
EF
は以下のいずれかでなければならない:
|
||
|
-
|
||
メンバー関数
新しい
scope_success
を構築する
(公開メンバ関数) |
|
スコープが正常に終了した場合に終了関数を呼び出し、
scope_success
がアクティブな場合に
scope_success
を破棄する
(公開メンバ関数) |
|
|
operator=
[deleted]
|
scope_success
は代入不可
(公開メンバ関数) |
修飾子 |
|
scope_success
を非アクティブにする
(公開メンバ関数) |
|
推論ガイド
注記
動的ストレージ期間を持つ
scope_success
の構築は、予期せぬ動作を引き起こす可能性があります。
別のスレッドで作成された
scope_success
から
scope_success
を構築すると、破棄時に異なるスレッドで取得された未捕捉例外のカウントが比較される可能性があるため、予期しない動作を引き起こす可能性もあります。
関数内で定義されたローカル変数(例: 参照でキャプチャされたラムダ)が
scope_success
オブジェクトに格納された
EF
によって参照され、かつその変数がその関数のreturnオペランドとして使用される場合、
scope_success
のデストラクタが実行されexit関数を呼び出す時点では、その変数は既にreturnされている可能性があります。これは予期せぬ動作を引き起こす可能性があります。
例
#include <iostream> #include <cstdlib> #include <string_view> #include <experimental/scope> void print_exit_status(std::string_view name, bool exit_status, bool did_throw) { std::cout << name << ":\n"; std::cout << " 例外スロー " << (did_throw ? "はい" : "いいえ") << "\n"; std::cout << " 終了ステータス " << (exit_status ? "完了" : "保留中") << "\n\n"; } // ランダムに例外をスロー(50%の確率) void maybe_throw() { if (std::rand() >= RAND_MAX / 2) throw std::exception{}; } int main() { bool exit_status{false}, did_throw{false}; // 「スコープ終了時」での手動処理 try { maybe_throw(); exit_status = true; } catch (...) { did_throw = true; } print_exit_status("手動処理", exit_status, did_throw); // scope_exitの使用:スコープ終了時(成功時または例外発生時)に実行 exit_status = did_throw = false; try { auto guard = std::experimental::scope_exit{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_exit", exit_status, did_throw); // scope_failの使用:例外発生時のみ実行 exit_status = did_throw = false; try { auto guard = std::experimental::scope_fail{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_fail", exit_status, did_throw); // scope_successの使用:例外が発生しなかった場合のみ実行 exit_status = did_throw = false; try { auto guard = std::experimental::scope_success{[&]{ exit_status = true; } }; maybe_throw(); } catch (...) { did_throw = true; } print_exit_status("scope_success", exit_status, did_throw); }
出力:
手動処理: 例外スロー はい 終了ステータス 保留中 scope_exit: 例外スロー いいえ 終了ステータス 完了 scope_fail: 例外スロー はい 終了ステータス 完了 scope_success: 例外スロー はい 終了ステータス 保留中
関連項目
|
関数オブジェクトをラップし、スコープ終了時に呼び出す
(クラステンプレート) |
|
|
関数オブジェクトをラップし、例外によるスコープ終了時に呼び出す
(クラステンプレート) |
|
|
(C++11)
|
unique_ptr
のためのデフォルト削除子
(クラステンプレート) |