如果通过引用捕获异常,可以修改它并重新抛出吗?

If you catch an exception by reference, can you modify it and rethrow?

本文关键字:新抛出 修改 引用 捕获异常 如果      更新时间:2023-10-16

标准对通过引用捕获的异常以及试图修改它会发生什么有任何规定吗?

考虑以下代码:

class my_exception: public std::logic_error
{
public:
    std::vector<std::string> callstack;
};
void MyFunc()
{
    try
    {
        SomethingThatThrows();
    }
    catch (my_exception & e)
    {
        e.callstack.push_back("MyFunc");
        throw;
    }
}

这是一个人为的例子,我实际上并没有尝试这样做。我只是好奇会发生什么,基于另一个线程的建议,异常应该被const引用捕获。

异常将会改变。

§15.3 (except.handle)/17:

当处理程序声明一个非常量对象时,对该对象的任何更改都不会影响临时对象通过执行throw表达式初始化的对象。

当处理程序声明引用时对于非常量对象,对引用对象的任何更改都是对初始化的临时对象的更改当throw表达式被执行时,如果该对象被重新抛出,它将生效。

因此,如果my_exceptionMyFunc之外被捕获,我们将在调用堆栈中看到"MyFunc"条目(例如http://ideone.com/5ytqN)

是的,你可以这样做。

当您使用throw;重新抛出当前异常时,不会生成副本:原始临时异常对象被重新抛出。因此,在处理程序中对该对象所做的任何更改都将在下次捕获异常对象时呈现在异常对象中。