递归变体和不完整类型的销毁

  • 本文关键字:类型 递归 c++ c++20
  • 更新时间 :
  • 英文 :


我正在尝试基于std::variant构建一个AST(我知道还有其他方法可以做到这一点,但我对围绕联合类型的方法特别感兴趣)。我有两个表达概念

  • 叶表达式
  • 递归表达式

我需要它才能使用std::variant(因为它不允许递归类型)。叶表达式可能如下所示:

struct NameExpr
{
std::string name;
};

以及这样的回避表达式:

struct CallExpr
{
Expr target;
std::vector<Expr> args;
};

Expr是所有表达式类型的总和:

struct BinaryExpr;
struct CallExpr;
using Expr = std::variant<
Recursive<BinaryExpr>,
Recursive<CallExpr>,
ConstantExpr,
NameExpr
>;

我必须转发声明我的递归表达式类型,因为它们的定义需要定义ExprRecursive基本上是一个std::unique_ptr。正如我所说,这个类只是为了打破Expr内部的类型循环。

我的问题是,像std::unique_ptr一样,我的Recursive有一个非平凡的析构函数,它删除了指向实际表达式的指针。但是,由于我必须转发声明我的递归类型,因此在实例化模板时,所有使用Recursive的类型都是不完整的,这反过来又会导致该实例化析构函数中的意外 (UB?) 行为。

我可以以某种方式解决此问题还是必须切换到其他设计?

(有点)地雷危险教育

添加一个~并复制/移动 ctor 并分配。然后在定义所有内容后默认它们。

您可能还希望Expr成为变体的薄包装器,以便您可以转发声明它。

最新更新