c++ - 将初始化列表与从空基类继承的结构一起使用

标签 c++ inheritance struct aggregate initializer-list

我的解析器正在创建一个抽象语法树,它由继承自空 Node 基础结构的 NodeSomething 结构组成。这些存储在 std::list<Node> 中.

我的问题是我不想为每个单独的 NodeSomething 编写构造函数,并且由于结构都是从基类继承的,因此它们不再是聚合,因此我不能使用初始化列表(大括号初始化) .

由于所有这些结构都相当简单,主要包含一个或两个 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旨在成为仅用于继承的抽象类,以便我可以存储不同节点类型的列表。

最佳答案

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

但是,基类的存在使对象无法成为聚合(在 C++14 和更早版本中);因此它不能应用聚合初始化。

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

关于c++ - 将初始化列表与从空基类继承的结构一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46963650/

相关文章:

c++ - 一个可以使用动态函数交换的函数

C++ 内存分配和重写 vector 类

c++ - 在调用基类之前需要调用成员的方法

c++ - avl树的实现导致segmentation fault

c++ - 将 WCHAR 数组作为 LPARAM 发送到 winproc 的正确方法是什么?

c++ - 函数的内存消耗/以可读性的名义创建更多函数?

c++ - 是否有可能在没有得到 "new"ed 的结构中有一个 boost::variant?

c - 结构体中数组的内存分配

c# - C# 和 C/C++ 中二进制到 float 转换的区别

java - 如何在 Scanner 的方法中存储类型信息