抛出和捕捉整数如何工作?


14

使用此代码:

int main()
{
    try
    {
        throw -1;
    }
    catch (int& x)
    {
        std::cerr << "We caught an int exception with value: " << x << std::endl;
    }
    std::cout << "Continuing on our merry way." << std::endl;

    return 0;
}

我们有:

/tmp$ ./prorgam.out
Continuing on our merry way
We caught an int exception with value: -1

catch块如何读-1int&?我们无法将值分配给非常量左值引用。

为什么第二条std::cout语句要在第一条std::cerr语句之前执行?


2
您确定这是您获得的确切输出吗?该We caught an int exception with value: -1行应首先打印。
HolyBlackCat

1
@Scheff,对不起,您是对的,第一个输出重定向到error streamnot standard stream
Ghasem Ramezani


2
@FrançoisAndrieux被允许的原因是发生了不同的语义。通常,对于临时文件,您不知道会发生什么情况,因此决定只允许const引用临时文件。除例外外,我们知道对象的生存期,我们可能需要对其进行修改并将其重新扔到更高的上下文中。为了促进这一点,该标准允许绑定到非常量左值引用。
NathanOliver

1
@FrançoisAndrieux throw创建一个副本(或移动)您传递给它的对象。引用绑定到该副本。副本是左值是有意义的。
HolyBlackCat

Answers:


10

可以,因为[except.throw] / 3

引发异常复制初始化(称为[dcl.init],[class.copy.ctor])一个临时对象,称为异常对象。表示临时变量的左值用于初始化在匹配处理程序中声明的变量([except.handle])。

重点矿

如您所见,即使它是临时的,编译器也将其视为用于初始化处理程序的左值。因此,您不需要const引用。


1
但是消息出现的顺序是什么?
托马什Zato -恢复莫妮卡

8

这个throw参考

与其他临时对象不同,在初始化catch子句参数时,异常对象被视为左值参数,因此可以通过左值引用对其进行捕获,修改和重新抛出。

因此,尽管“对象”是临时的,但它仍然是左值,因此您可以通过引用来捕获它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.