从成员构造函数抛出异常(大括号初始化程序与初始化程序列表)

Art*_*zuk 9 c++

我在理解在成员对象初始化期间抛出异常(来自构造函数)时发生的事情时,我已经失去了信心(可能还有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-initializermember-initializer-list 初始化成员有什么区别?

错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi? id = 85363

Jon*_*ely 1

以下之间应该没有实际区别:

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