如果结构继承,则无法使用初始值设定项列表初始化结构?

Can't initialize a struct using an initializer list if it inherits?

本文关键字:结构 列表 初始化 继承 如果      更新时间:2023-10-16

我对我写的(C++14)代码片段感到困惑:

struct B {};
struct C     { int m; };
struct D : B { int m; };
int main() {
    C c = { 1 }; // this works
    D d = { 1 }; // this doesn't work
}

我自己为D编写构造函数很好,但我找不到一个很好的解释来解释为什么结构D不再可以用初始化器列表初始化。我所改变的只是让它从一个完全空的类继承——我想我以某种方式让它表现得不像结构。

我的编译器究竟是如何以不同的方式处理结构CD的?

它适用于C,因为它是一个聚合,因此它使用聚合初始化,但D不是聚合,因为它有基类。正如你提到的,显而易见的工作就是编写一个构造函数。

这在C++标准草案8.5.1 Aggregates[dcl.init.agr]一节中有介绍,重点是mine:

聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),无基类(第10条),无虚拟函数(10.3)。

有一个建议:扩展到聚合初始化,以消除这一限制。正如chris所指出的,进化工作组已经接受了这一点,但据我所知,现在也需要Core接受。

D不再是聚合类型,因此无法使用初始化列表直接初始化。如果你提供了一个构造函数,那么它就会工作。

struct B {};
struct C     { int m; };
struct D : B { int m; D(int m_) : m(m_) {} };
int main() 
{
    C c = { 1 }; // this works
    D d = { 1 }; // this works
}

实时示例

结构c是POD,而结构D是对象。类初始值设定项规则由于继承而应用。