命名空间
变体
操作

try

来自 cppreference.com
< cpp‎ | language
 
 
C++ 语言
表达式
替代表示
字面量
布尔值 - 整数 - 浮点数
字符 - 字符串 - 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 构造函数初始化器 (可选) 复合语句 处理程序序列 (2)
2) 函数 try复合语句 必须是函数体中的复合语句部分。
复合语句 - 一个 复合语句
处理程序序列 - 一个非空 处理程序 序列
构造函数初始化器 - 成员初始化列表(仅限于 构造函数

[编辑] 普通 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 块是一种特殊的 函数体

如果从它的 复合语句构造函数初始化器(如果有)抛出异常,该异常将与它的 处理程序序列  中的 处理程序 匹配。

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 块的处理程序中引用对象的任何非静态成员或基类会导致未定义的行为。

如果 return 语句 出现在构造函数的函数 try 块的处理程序中,则程序格式错误。

如果控制到达构造函数或析构函数的函数 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
是否会捕获来自基类或成员析构函数的异常
此类异常
被捕获

[编辑] 另请参阅