为什么匿名临时例外可以绑定到捕获站点的参考?

发布于 2025-01-25 04:15:23 字数 272 浏览 1 评论 0原文

考虑

#include <iostream>

struct Foo{};

int main(){
    try {
        throw Foo();
    } catch (Foo& e){
        std::cout << "Caught";
    }
}

输出 ,但是为什么呢?我以为catch应该是const foo&amp;。我忘记了什么?

Consider

#include <iostream>

struct Foo{};

int main(){
    try {
        throw Foo();
    } catch (Foo& e){
        std::cout << "Caught";
    }
}

The output is Caught, but why? I would have thought that the catch should have been const Foo&. What am I forgetting?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

来日方长 2025-02-01 04:15:23

我本来以为捕获物应该是const foo&amp;。

它不需要。

我怀疑您期望的是,将LVALUE引用到非const的情况下会存在问题。

[异常]

从异常对象(类型e)初始化的CV T或CV T&amp;的变量,如下:

  • 如果T是E ...
  • 的基类

  • 否则,该变量是从 lvalue e Excect对象的 lvalue copy-initialized([dcl.init])。

当处理程序退出时,变量的寿命是在处理程序中初始化自动存储持续时间的任何对象后的终止。

请注意突出显示的“ LVALUE”。将非符合级别的引用绑定到LVALUE是没有问题的。


Sidenotes:

如果

  • 处理程序是CV T型或CV T&amp; E和T是相同的类型(忽略顶级CV-Qualifier)或

忽略了顶级CV预选赛,并且不需要在抛出的对象和处理程序类型之间匹配。

...当处理程序声明对对象的引用时,引用对象的任何更改都是对异常对象的更改,如果重新启用该对象。

捕获参考可以修改异常对象。

I would have thought that the catch should have been const Foo&.

It doesn't need to be.

I suspect that you are expecting that there would be a problem with binding of an lvalue reference to non-const.

[except.handle]

The variable declared by the exception-declaration, of type cv T or cv T&, is initialized from the exception object, of type E, as follows:

  • if T is a base class of E ...
  • otherwise, the variable is copy-initialized ([dcl.init]) from an lvalue of type E designating the exception object.

The lifetime of the variable ends when the handler exits, after the destruction of any objects with automatic storage duration initialized within the handler.

Note the highlighted "lvalue". There's no problem binding a non-const lvalue reference to an lvalue.


Sidenotes:

A handler is a match for an exception object of type E if

  • The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifiers), or

Top level cv qualifiers are ignored and don't need to match between thrown object and handler type.

... When the handler declares a reference to an object, any changes to the referenced object are changes to the exception object and will have effect should that object be rethrown.

Catching a reference allows modifying the exception object.

夜声 2025-02-01 04:15:23

这是因为在lvalue中考虑了抛出的对象。 [except.handle]/14 state:

按异常删除声明的变量cv tcv t&amp;是从异常对象初始化的,类型e ,如下:

  • 如果te的基类,则该变量是从类型的lvalue中复制initialized([dcl.init]) t指定异常对象的相应基类子对象;

  • 否则,该变量是从类型e指定异常对象的lvalue的复制initialized([dcl.init])。

当处理程序退出时,变量的寿命是在处理程序中初始化自动存储持续时间的任何对象后的终止。

This is because the thrown object is considered in lvalue. [except.handle]/14 states:

The variable declared by the exception-declaration, of type cv T or cv T&, is initialized from the exception object, of type E, as follows:

  • if T is a base class of E, the variable is copy-initialized ([dcl.init]) from an lvalue of type T designating the corresponding base class subobject of the exception object;

  • otherwise, the variable is copy-initialized ([dcl.init]) from an lvalue of type E designating the exception object.

The lifetime of the variable ends when the handler exits, after the destruction of any objects with automatic storage duration initialized within the handler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文