将initalizer列表与从空基类继承的结构一起使用

Using initalizer lists with structs that inherit from empty base class

本文关键字:结构 一起 继承 基类 列表 initalizer      更新时间:2023-10-16

我的解析器正在创建一个抽象语法树,由NodeSomething结构组成,这些结构继承自一个空的Node基结构。这些存储在CCD_ 1中。

我的问题是,我不想为每个NodeSomething编写构造函数,因为结构都继承自基类,所以它们不再是聚合的,因此我不能使用initaliser列表(大括号initalisation)。

由于所有这些结构都相当简单,大多包含一两个int或string变量,因此必须为所有这些结构编写基本构造函数似乎非常复杂。我不需要继承,但看不到任何更好的方法来创建各种Node子类的通用列表。

总之,这里有一些经过修剪的代码示例来解释我的意思:

struct Node {};
struct NodePerson : Node
{
std::string name;
int age;
};
struct NodeVariable : Node
{
int val;
};

然后在实现中,类似于这样的东西:

std::list<Node> tree;
tree.push_back(NodePerson {"Paul", 23});

这将抛出一个no matching constructor for initalization of 'NodePerson'错误,然后3个关于隐式移动、复制和默认构造函数的参数不匹配的注释(2给定1)。

据我所知,这是预期的行为,因为结构不再是聚合的,不能使用大括号初始化,但必须为每个结构编写构造函数似乎非常不令人担忧。有简单的解决方案吗?

编辑:由于我没有明确表示Node是一个仅用于继承的抽象类,因此我可以存储不同Node类型的列表。

您正试图使用聚合初始化,这是为对象的每个数据成员提供一个支持的初始化程序列表的过程,绕过对象可能具有的任何构造函数。

然而,基类的存在使对象失去了聚合的资格(在C++14及更早版本中);因此它不能应用聚合初始化。

在C++17中,"聚合"的定义正在扩展,您的代码将合法化。如果您还不能使用C++17编译器,那么您将不得不求助于其他选项,例如添加构造函数。