我对于在成员对象初始化期间(从构造函数中)抛出异常的情况失去了信心(也可能浪费了2个小时)。
让我给你举个例子:
int init (int f) {
throw f;
}
struct X {
X (int f) : n {init (f)} {}
int n;
};
struct P {
X x {20};
};
以及使用方法:
int main (int argc, char** argv) {
try {
P p {};
}
catch (int n) {
std::cout << n << "\n";
}
}
这段代码(C++11模式)在GCC 7.2.1中可以编译通过,在Linux(Centos 7.4.1708)下运行时会出现以下结果:
terminate called after throwing an instance of 'int'
[1] 1242 abort (core dumped) ./main
问题是:为什么?为什么
catch()
段没有被执行?
我已经追踪了这个问题,意味着我的P
类有点不同:struct P {
P (int f) : x {f} {}
X x;
};
并且使用以下形式初始化
p
对象: P p {20}
,结果是: 20,这是预期的,没有核心转储。在异常上下文中,有谁能解释一下使用 花括号或等号初始化程序 和 成员初始化器列表 初始化成员之间的区别吗?
缺陷报告: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85363
-std=c++11
编译您的代码会产生您提到的结果,但使用c++14
或c++17
一切看起来都很好。 - JBLP() {}
可以捕获异常,但是P() = default;
没有帮助。std::is_nothrow_default_constructible<P>::value;
似乎为true
,这是一个问题。似乎在决定默认构造函数是否 noexcept 时,默认成员初始值器不被考虑在内。 - François Andrieuxstd::is_nothrow_default_constructible<P>::value;
是 false,即使它没有捕获到异常。 - eerorikag++ -std=c++11
进行复现,但是无法在Visual C++ 2017(对于任何值的/std:
)中进行复现。请报告此错误。 - Cheers and hth. - Alf