例外
例外処理は、プログラムの実行中にある地点から、実行が以前に通過した地点に関連付けられたハンドラに制御と情報を転送する方法を提供します (言い換えれば、例外処理はコールスタックを遡って制御を転送します)。
throw 式を評価すると例外が送出されます。例外は他の文脈でも送出されることがあります。
例外が捕捉されるためには、throw 式が try ブロック の内側になければならず、その try ブロックは例外オブジェクトの型に一致するハンドラを含んでいなければなりません。
関数を宣言する際に、関数が送出しうる例外の型を制限するために、以下の指定を行うことができます。
| (C++17まで) |
| (C++11以降) |
例外処理中に発生したエラーは std::terminate および std::unexpected(C++17まで) によって処理されます。
目次 |
[編集] 使用法
throw 式は、任意の理由で実行スタックを遡って任意のコードブロックに制御を移すために使用できますが (std::longjmp と同様)、その意図された用途はエラー処理です。
[編集] エラー処理
例外の送出は、関数からのエラーを通知するために使用されます。ここで「エラー」とは、通常、以下のものに限定されます。[1][2][3]
- 有効な戻り値オブジェクトを生成できないなど、事後条件を満たせなかった場合。
- 呼び出す必要のある別の関数の事前条件を満たせなかった場合。
- (非 private メンバ関数の場合) クラスの不変条件を(再)確立できなかった場合。
特に、これはコンストラクタの失敗 (RAII も参照) やほとんどの演算子の失敗は、例外を送出することで報告されるべきであることを意味します。
さらに、いわゆる「ワイドコントラクト (wide contract)」な関数は、許容できない入力を示すために例外を使用します。例えば、std::basic_string::at は事前条件を持ちませんが、範囲外のインデックスを示すために例外を送出します。
[編集] 例外安全性
関数によってエラー条件が報告された後、プログラムの状態に関して追加の保証が提供されることがあります。一般的に、以下の4つのレベルの例外保証が認識されており[4][5][6]、これらは互いに厳密な上位集合となっています。
- 送出しない (nothrow) (または失敗しない (nofail)) 例外保証 — 関数は決して例外を送出しません。送出しない保証 (エラーは他の手段で報告されるか隠蔽される) は、デストラクタやスタック巻き戻し中に呼び出される可能性のある他の関数に期待されます。デストラクタはデフォルトで
noexceptです。(C++11から) 失敗しない保証 (関数は常に成功する) は、swap 関数、ムーブコンストラクタ、および強い例外保証を提供する関数によって使用される他の関数に期待されます。 - 強い例外保証 — 関数が例外を送出した場合、プログラムの状態は関数呼び出しの直前の状態にロールバックされます (例: std::vector::push_back)。
- 基本的な例外保証 — 関数が例外を送出した場合でも、プログラムは有効な状態にあります。リソースリークはなく、すべてのオブジェクトの不変条件は維持されます。
- 例外保証なし — 関数が例外を送出した場合、プログラムは有効な状態にないかもしれません。リソースリーク、メモリ破壊、またはその他の不変条件を破壊するエラーが発生している可能性があります。
ジェネリックコンポーネントは、さらに例外中立な保証を提供する場合があります。テンプレートパラメータから例外が送出された場合 (例: std::sort の Compare 関数オブジェクトから、または std::make_shared の T のコンストラクタから)、それは変更されずに呼び出し元に伝播されます。
[編集] 例外オブジェクト
任意の完全な型のオブジェクトと void への cv ポインタは例外オブジェクトとして送出できますが、すべての標準ライブラリ関数は名前のないオブジェクトを値で送出し、それらのオブジェクトの型は std::exception から (直接または間接的に) 派生しています。ユーザー定義の例外も通常このパターンに従います。[7][8][9]
例外オブジェクトの不必要なコピーやオブジェクトスライシングを避けるため、ハンドラでは参照で捕捉することがベストプラクティスです。[10][11][12][13]
[編集] ノート
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_constexpr_exceptions |
202411L |
(C++26) | constexpr 例外 |
[編集] 外部リンク
|