我在理解在成员对象初始化期间抛出异常(来自构造函数)时发生的事情时,我已经失去了信心(可能还有2个小时).
让我告诉你一个例子:
int init (int f) {
throw f;
}
struct X {
X (int f) : n {init (f)} {}
int n;
};
struct P {
X x {20};
};
Run Code Online (Sandbox Code Playgroud)
和用法:
int main (int argc, char** argv) {
try {
P p {};
}
catch (int n) {
std::cout << n << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码(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
Run Code Online (Sandbox Code Playgroud)
问题是:为什么?
为什么catch()不采取部分?
我已经跟踪了这个问题,这意味着当我的P班级看起来有点不同时:
struct P {
P (int f) : x {f} {}
X x;
};
Run Code Online (Sandbox Code Playgroud)
并以p这种形式初始化对象:P p {20}结果是:20,这是预期的,没有核心转储.
有人可以解释一下,在异常情况下使用brace-or-equal-initializer和member-initializer-list 初始化成员有什么区别?
以下之间应该没有实际区别:
struct P {
X x {20};
};
Run Code Online (Sandbox Code Playgroud)
和
struct P {
P() : x{20} { }
X x;
};
Run Code Online (Sandbox Code Playgroud)
但是C++11 模式(但不是 C++14 或更高版本)存在一个GCC 错误p{},它会导致 的初始化发生在 try 块之外,或者将 的等效项添加到 的noexcept隐式定义的默认构造函数中
P。