【问题标题】:How does throwing and catching ints work?投掷和捕捉整数是如何工作的?
【发布时间】:2020-04-12 04:36:50
【问题描述】:

使用此代码:

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 块如何将-1 读取为int&amp;?我们无法为非常量左值引用赋值。

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

【问题讨论】:

  • 你确定这是你得到的确切输出吗? We caught an int exception with value: -1 应该先打印出来。
  • @Scheff,对不起,你是对的,第一个输出重定向到 error stream 而不是 standard stream
  • @FrançoisAndrieux 允许它的原因是存在不同的语义。通常,对于临时对象,您不知道会发生什么,因此决定只允许对临时对象进行 const 引用。除了例外,我们知道对象的生命周期,我们可能想要修改它并将它重新抛出到更高的上下文中。为了促进这一点,该标准允许绑定到非 const 左值引用。
  • @FrançoisAndrieux throw 创建一个副本(或移动)您传递给它的对象。引用绑定到该副本。副本是左值是有道理的。

标签: c++ exception try-catch


【解决方案1】:

来自this throw reference

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

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

【讨论】:

    【解决方案2】:

    这没关系,因为[except.throw]/3

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

    强调我的

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

    【讨论】:

    • 但是消息出现的顺序是什么?
    猜你喜欢
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    相关资源
    最近更新 更多