名前空間
変種
操作

例外

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

例外処理は、プログラムの実行中にある地点から、実行が以前に通過した地点に関連付けられたハンドラに制御と情報を転送する方法を提供します (言い換えれば、例外処理はコールスタックを遡って制御を転送します)。

throwを評価すると例外が送出されます。例外は他の文脈でも送出されることがあります。

例外が捕捉されるためには、throw 式が try ブロック の内側になければならず、その try ブロックは例外オブジェクトの型に一致するハンドラを含んでいなければなりません。

関数を宣言する際に、関数が送出しうる例外の型を制限するために、以下の指定を行うことができます。

(C++17まで)
(C++11以降)

例外処理中に発生したエラーは std::terminate および std::unexpected(C++17まで) によって処理されます。

目次

[編集] 使用法

throw 式は、任意の理由で実行スタックを遡って任意のコードブロックに制御を移すために使用できますが (std::longjmp と同様)、その意図された用途はエラー処理です。

[編集] エラー処理

例外の送出は、関数からのエラーを通知するために使用されます。ここで「エラー」とは、通常、以下のものに限定されます。[1][2][3]

  1. 有効な戻り値オブジェクトを生成できないなど、事後条件を満たせなかった場合。
  2. 呼び出す必要のある別の関数の事前条件を満たせなかった場合。
  3. (非 private メンバ関数の場合) クラスの不変条件を(再)確立できなかった場合。

特に、これはコンストラクタの失敗 (RAII も参照) やほとんどの演算子の失敗は、例外を送出することで報告されるべきであることを意味します。

さらに、いわゆる「ワイドコントラクト (wide contract)」な関数は、許容できない入力を示すために例外を使用します。例えば、std::basic_string::at は事前条件を持ちませんが、範囲外のインデックスを示すために例外を送出します。

[編集] 例外安全性

関数によってエラー条件が報告された後、プログラムの状態に関して追加の保証が提供されることがあります。一般的に、以下の4つのレベルの例外保証が認識されており[4][5][6]、これらは互いに厳密な上位集合となっています。

  1. 送出しない (nothrow) (または失敗しない (nofail)) 例外保証 — 関数は決して例外を送出しません。送出しない保証 (エラーは他の手段で報告されるか隠蔽される) は、デストラクタやスタック巻き戻し中に呼び出される可能性のある他の関数に期待されます。デストラクタはデフォルトで noexcept です。(C++11から) 失敗しない保証 (関数は常に成功する) は、swap 関数、ムーブコンストラクタ、および強い例外保証を提供する関数によって使用される他の関数に期待されます。
  2. 強い例外保証 — 関数が例外を送出した場合、プログラムの状態は関数呼び出しの直前の状態にロールバックされます (例: std::vector::push_back)。
  3. 基本的な例外保証 — 関数が例外を送出した場合でも、プログラムは有効な状態にあります。リソースリークはなく、すべてのオブジェクトの不変条件は維持されます。
  4. 例外保証なし — 関数が例外を送出した場合、プログラムは有効な状態にないかもしれません。リソースリーク、メモリ破壊、またはその他の不変条件を破壊するエラーが発生している可能性があります。

ジェネリックコンポーネントは、さらに例外中立な保証を提供する場合があります。テンプレートパラメータから例外が送出された場合 (例: std::sortCompare 関数オブジェクトから、または std::make_sharedT のコンストラクタから)、それは変更されずに呼び出し元に伝播されます。

[編集] 例外オブジェクト

任意の完全な型のオブジェクトと void への cv ポインタは例外オブジェクトとして送出できますが、すべての標準ライブラリ関数は名前のないオブジェクトを値で送出し、それらのオブジェクトの型は std::exception から (直接または間接的に) 派生しています。ユーザー定義の例外も通常このパターンに従います。[7][8][9]

例外オブジェクトの不必要なコピーやオブジェクトスライシングを避けるため、ハンドラでは参照で捕捉することがベストプラクティスです。[10][11][12][13]

[編集] ノート

機能テストマクロ 規格 機能
__cpp_constexpr_exceptions 202411L (C++26) constexpr 例外

[編集] 外部リンク

  1. H. Sutter (2004) "When and How to Use Exceptions" in Dr. Dobb's
  2. H. Sutter, A. Alexandrescu (2004), "C++ Coding Standards", Item 70
  3. C++ Core Guidelines I.10: Use exceptions to signal a failure to perform a required task
  4. B. Stroustrup (2000), "The C++ Programming Language" Appendix E
  5. H. Sutter (2000) "Exceptional C++"
  6. D. Abrahams (2001) "Exception Safety in Generic Components"
  7. D. Abrahams (2001) "Error and Exception Handling"
  8. isocpp.org Super-FAQ "What should I throw?"
  9. C++ Core Guidelines E.14: Use purpose-designed user-defined types as exceptions (not built-in types)
  10. C++ Core Guidelines E.15: Throw by value, catch exceptions from a hierarchy by reference
  11. S. Meyers (1996) "More Effective C++" Item 13
  12. isocpp.org Super-FAQ "What should I catch?"
  13. H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" Item 73
English 日本語 中文(简体) 中文(繁體)