名前空間
変種
操作

tryブロック

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
throw
tryブロック
名前空間
指定子
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

特殊メンバ関数
テンプレート
その他
 
 
例外
tryブロック
例外を送出する
例外を処理する
例外仕様
    noexcept 指定 (C++11)
    動的例外指定 (C++17* まで)
noexcept 演算子 (C++11)
 

例外は、try ブロック内でスローされた場合、関連するハンドラによって処理される可能性があります。

目次

[編集] 構文

try 複合ステートメント ハンドラ列 (1)
try ctor-initializer (オプション) 複合ステートメント ハンドラ列 (2)
2) 関数 try ブロック複合ステートメントは、関数本体の複合ステートメントコンポーネントでなければなりません。
compound-statement - a 複合ステートメント
ハンドラ列 - 非空のハンドラのシーケンス
ctor-initializer - メンバ初期化子リスト(コンストラクタのみ)

[編集] 通常の try ブロック

通常の try ブロックはステートメントです。

その 複合ステートメント から例外がスローされた場合、その例外は ハンドラ列ハンドラ と照合されます。

void f()
{
    throw 1;     // NOT handled by the handler below
    try
    {
        throw 2; // handled by the associated handler
    }
    catch (...)
    {
        // handles the exception 2
    }
    throw 3;     // NOT handled by the handler above
}

[編集] 関数 try ブロック

関数 try ブロックは、特殊な種類の関数本体です。

その 複合ステートメント または ctor-initializer (もしあれば) から例外がスローされた場合、その例外は ハンドラ列ハンドラ と照合されます。

int f(bool cond)
{
    if (cond)
        throw 1;
    return 0;
}
 
struct X
{
    int mem;
 
    X() try : mem(f(true)) {}
    catch (...)
    {
        // handles the exception 1
    }
 
    X(int) try
    {
        throw 2;
    }
    catch (...)
    {
        // handles the exception 2
    }
};

静的記憶域期間を持つオブジェクトのデストラクタ、または静的記憶域期間を持つ非ブロック変数に関連付けられたオブジェクトのコンストラクタでスローされた例外は、main 関数上の関数 try ブロックによって捕捉されません。

スレッド記憶域期間を持つオブジェクトのデストラクタ、またはスレッド記憶域期間を持つ非ブロック変数に関連付けられたオブジェクトのコンストラクタでスローされた例外は、スレッドの初期関数上の関数 try ブロックによって捕捉されません。

(C++11以降)

関数がコンストラクタまたはデストラクタでない限り(以下を参照)、関数 try ブロックの ハンドラ複合ステートメント の末尾を越えてフローすることは、その関数 try ブロックの 複合-ステートメント の末尾を越えてフローすることと同等です。

[編集] コンストラクタとデストラクタの try ブロック

クラス C の場合、そのコンストラクタまたはデストラクタ定義の関数本体が関数 try ブロックであり、C のサブオブジェクトの初期化または破棄中に例外がスローされた場合、その例外は関数 try ブロックの ハンドラ列ハンドラ とも照合されます。

int f(bool cond = true)
{
    if (cond)
        throw 1;
    return 0;
}
 
struct X
{
    int mem = f();
 
    ~X()
    {
        throw 2;
    }
};
 
struct Y
{
    X mem;
 
    Y() try {}
    catch (...)
    {
        // handles the exception 1
    }
 
    ~Y() try {}
    catch (...)
    {
        // handles the exception 2
    }
};

コンストラクタまたはデストラクタの関数 try ブロックのハンドラ内で、そのオブジェクトの非静的メンバまたは基底クラスを参照すると、未定義の動作になります。

コンストラクタの関数 try ブロックのハンドラ内に return ステートメント が現れた場合、プログラムは不正です。

コンストラクタまたはデストラクタの関数 try ブロックのハンドラの末尾に制御が達した場合、現在処理中の例外が再スローされます。

[編集] 制御フロー

try ブロックの 複合ステートメント は、制御フロー制限付きステートメントです。

void f()
{
    goto label;     // error
    try
    {
        goto label; // OK
        label: ;
    }
    catch (...)
    {
        goto label; // error
    }
}

ジャンプステートメントgotobreakreturncontinue)は、try ブロック(そのハンドラを含む)から制御を転送するために使用できます。この場合、try ブロック内で宣言された各変数は、その宣言を直接含むコンテキストで破棄されます。

try
{
    T1 t1;
    try
    {
        T2 t2;
        goto label; // destroy t2 first, then t1
    }
    catch(...)
    {
        // executed if an exception is thrown while destroying t2
    }
}
catch(...)
{
    // executed if an exception is thrown while destroying t1
}
label: ;

[編集] キーワード

try

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 98 C++98 switch ステートメントは制御を転送できます。
try ブロックの 複合ステートメント 内へ
禁止された
CWG 1167 C++98 デストラクタ上の関数 try ブロックが
基底またはメンバデストラクタからの例外を捕捉するかどうかは未指定でした。
そのような例外
は捕捉されます

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)