考虑这个简短的片段:
struct B {
B() = default;
explicit B(B const& ) { }
};
struct D : B { };
int main() {
try {
throw D{};
}
catch(B ) {
}
}
gcc 接受这段代码,clang 认为它格式错误:
main.cpp:17:13: error: no matching constructor for initialization of 'B'
catch(B ) {
^
谁是对的?
最佳答案
我认为这是一个 gcc 错误(由于还没有人否决这个答案,我将其提交为 70375)。
两个编译器都正确地同意应该捕获 D{}
,根据 [except.handle]/3 ,它只检查 B
是 D
的基类。
但是handler的初始化定义在[except.handle]/15中作为:
The variable declared by the exception-declaration, of type cv
T
or cvT&
, is initialized from the exception object, of typeE
, as follows:
— ifT
is a base class ofE
, the variable is copy-initialized (8.5) from the corresponding base class subobject of the exception object;
这意味着初始化工作为:
D __temporary_object{};
B __handler = static_cast<B&>(__temporary_object);
这应该是不允许的,因为 B
的复制构造函数被标记为 explicit
(并且复制初始化不会削减它)。
关于c++ - 按值捕获异常 - gcc 和 clang 不同意,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36168799/