为什么匿名临时异常可以绑定到捕获站点的引用?
Why can an anonymous temporary exception be bound to a reference at a catch site?
考虑
#include <iostream>
struct Foo{};
int main(){
try {
throw Foo();
} catch (Foo& e){
std::cout << "Caught";
}
}
输出是Caught
,但为什么呢?我本以为 catch
应该是 const Foo&
。我忘记了什么?
这是因为抛出的对象被认为是左值。 [except.handle]/14 状态:
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.
I would have thought that the catch should have been const Foo&.
不需要。
我怀疑您期望将左值引用绑定到 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.
注意突出显示的“左值”。将 non-const 左值引用绑定到左值没有问题。
旁注:
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
顶级 cv 限定符被忽略,不需要匹配抛出的对象和处理程序类型。
... 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.
捕获引用允许修改异常对象。
考虑
#include <iostream>
struct Foo{};
int main(){
try {
throw Foo();
} catch (Foo& e){
std::cout << "Caught";
}
}
输出是Caught
,但为什么呢?我本以为 catch
应该是 const Foo&
。我忘记了什么?
这是因为抛出的对象被认为是左值。 [except.handle]/14 状态:
The variable declared by the exception-declaration, of type
cv T
orcv T&
, is initialized from the exception object, of typeE
, as follows:
if
T
is a base class ofE
, the variable is copy-initialized ([dcl.init]) from an lvalue of typeT
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.
I would have thought that the catch should have been const Foo&.
不需要。
我怀疑您期望将左值引用绑定到 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.
注意突出显示的“左值”。将 non-const 左值引用绑定到左值没有问题。
旁注:
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
顶级 cv 限定符被忽略,不需要匹配抛出的对象和处理程序类型。
... 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.
捕获引用允许修改异常对象。