【发布时间】:2018-02-21 15:39:23
【问题描述】:
我对成员对象初始化期间(从构造函数)抛出异常时会发生什么失去了信心(可能是 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,这是预期的,没有核心转储。
有人能解释一下在异常情况下使用 brace-or-equal-initializer 和 member-initializer-list 初始化成员有什么区别吗?
【问题讨论】:
-
有趣的是,使用
-std=c++11编译代码会产生您提到的结果,但使用c++14或c++17看起来一切都很好。 -
对我来说似乎是一个编译器错误。考虑到 JBL 的发现,并且代码在 c++11 模式下的 clang++ 中运行良好。而且我认为程序没有任何问题
-
我可以用 VS2015 重现这个。添加
P() {}允许捕获异常,但P() = default;没有帮助。std::is_nothrow_default_constructible<P>::value;似乎是true,这是一个问题。在决定默认构造函数的noexceptness 时,似乎没有考虑默认成员初始化器。 -
@FrançoisAndrieux 这很奇怪。
std::is_nothrow_default_constructible<P>::value;是 false in g++,即使它确实无法捕获。
标签: c++