Namespaces
Variants

try block

From ja.cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

目次

構文

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

通常の try ブロック

通常の try ブロックは 文 です。

例外がその compound-statement からスローされた場合、その例外は handlers 内の handler-seq と照合されます:

void f()
{
    throw 1;     // 以下のハンドラでは処理されない
    try
    {
        throw 2; // 関連付けられたハンドラで処理される
    }
    catch (...)
    {
        // 例外2を処理する
    }
    throw 3;     // 上記のハンドラでは処理されない
}

関数 try ブロック

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

例外がその compound-statement または ctor-initializer (存在する場合)からスローされた場合、その例外は handlers 内の handler-seq と照合されます:

int f(bool cond)
{
    if (cond)
        throw 1;
    return 0;
}
struct X
{
    int mem;
    X() try : mem(f(true)) {}
    catch (...)
    {
        // 例外1を処理します
    }
    X(int) try
    {
        throw 2;
    }
    catch (...)
    {
        // 例外2を処理します
    }
};

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

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

(C++11以降)

関数の compound-statement の終端から抜け出すことは、 handler の try ブロックの終端から抜け出すことと等価です。ただし、その関数がコンストラクタまたはデストラクタである場合を除きます(下記参照)。

コンストラクタとデストラクタ try ブロック

クラス C について、そのコンストラクタまたはデストラクタの定義の関数本体が関数 try ブロックである場合、そして例外がそれぞれ C のサブオブジェクトの初期化中または破棄中にスローされると、その例外は関数 try ブロックの handler-seq 内の ハンドラ とも照合されます:

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 (...)
    {
        // 例外1を処理
    }
    ~Y() try {}
    catch (...)
    {
        // 例外2を処理
    }
};

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

コンストラクタの関数 try ブロックのハンドラ内で return 文 が現れた場合、プログラムは不適格となります。

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

制御フロー

compound-statement は try ブロックの control-flow-limited statement です:

void f()
{
    goto label;     // エラー
    try
    {
        goto label; // OK
        label: ;
    }
    catch (...)
    {
        goto label; // エラー
    }
}

ジャンプ文 (jump statement) ( goto , break , return , continue ) を使用して、 try ブロック(およびそのハンドラを含む)から制御を転送することができます。これが発生すると、 try ブロック内で宣言された各変数は、その宣言を直接含むコンテキストで破棄されます:

try
{
    T1 t1;
    try
    {
        T2 t2;
        goto label; // 最初にt2を破棄し、その後t1を破棄
    }
    catch(...)
    {
        // t2の破棄中に例外がスローされた場合に実行
    }
}
catch(...)
{
    // t1の破棄中に例外がスローされた場合に実行
}
label: ;

キーワード

try

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 98 C++98 switch 文が制御を
compound-statement 内の try ブロックに
転送可能であった
禁止
CWG 1167 C++98 デストラクタの関数 try ブロックが
基底クラスまたはメンバのデストラクタからの
例外を捕捉するかどうかが未規定であった
そのような例外は
捕捉される

関連項目