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

时间:2018-02-21 15:39:24

标签: c++

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

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

1 个答案:

答案 0 :(得分:1)

之间应该没有实际区别:

struct P {
    X x {20};
};

struct P {
    P() : x{20} { }
    X x;
};

但是对于C ++ 11模式(但不是C ++ 14或更高版本)有一个GCC bug会导致p{}的初始化发生在try-block之外,或者添加相当于noexcept为隐式定义的默认构造函数 P