为什么要捕获一个const int和一个int&work?

san*_*ank 5 c++ const exception

在下面的代码中,我抛出一个int,将其作为const int&捕获,重新抛出它并再次捕获它将其作为int&捕获.

#include <iostream>

int main()
{
    try
    {
        try
        {
            int x = 1;
            throw x;
        }
        catch(const int& e)
        {
            std::cout << "Inner catch" << std::endl;
            throw;
        }
    }
    catch(int & e1)
    {
        std::cout << "Outer catch" << std::endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述程序编译成功并打印

Inner catch
Outer catch
Run Code Online (Sandbox Code Playgroud)

另一方面,下面的程序,我试图初始化一个int和一个const int,甚至不会编译.

#include <iostream>
int main()
{
    int x = 0;
    const int& y = x;
    int& z = y 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我按预期得到以下错误

binding ‘const int’ to reference of type ‘int&’ discards qualifiers
     int& z = y
Run Code Online (Sandbox Code Playgroud)

为什么我被允许捕获一个const int&作为一个int&但是不能指定cons int和int&?

Swo*_*ish 13

除了.handle/3:

处理程序是E类型的异常对象的匹配,如果
(3.1) - 处理程序的类型为cv Tcv T&ET是相同的类型(忽略顶级cv限定符),或[.. ]


Dav*_*rtz 6

抛出始终是值.const如果需要,您可以使用或使用引用来捕获它,但抛出的对象始终是副本.所以用non来捕获它const并修改它是完全安全的.您可以通过打印a的地址来测试int它,然后抛出它,通过引用捕获它,并打印引用的地址.你会看到它是一个不同的地址.

你甚至可以这样做:

try
{
    throw 3;
}
catch (int& q)
{
    q = 4;
}
Run Code Online (Sandbox Code Playgroud)

带有值的抛出对象的值3被修改,因为q绑定到int使用抛出值初始化的新对象.你总是抛出一个值.

例外是throw;,它会重新抛出现有对象.它必须是这种方式,否则,不可能理智地管理抛出对象的生命周期.