How to manage ownership of recursive AST nodes with std::unique_ptr in C++17?
18:54 08 Dec 2025

I’m writing a small C compiler front-end in C++17 as a learning project.
My parser builds an AST for expressions, and I’m not sure about the best way to handle ownership for child nodes.

Here is a minimal example:

#include 

enum class NodeKind { IntegerLiteral, BinaryExpr };
enum class BinaryOp { Add, Sub };

struct Node {
    NodeKind kind;
    virtual ~Node() = default;
};

struct IntegerLiteral : Node {
    int value;
    explicit IntegerLiteral(int v) : value(v) {
        kind = NodeKind::IntegerLiteral;
    }
};

struct BinaryExpr : Node {
    BinaryOp op;
    Node* lhs;   // raw pointers for now
    Node* rhs;

    BinaryExpr(BinaryOp op, Node* lhs, Node* rhs)
        : op(op), lhs(lhs), rhs(rhs) {
        kind = NodeKind::BinaryExpr;
    }

    ~BinaryExpr() {
        delete lhs;
        delete rhs;
    }
};

Parser code (simplified):

Node* parseAdditiveExpr() {
    Node* left = parsePrimaryExpr();
    while (/* see + or - */) {
        BinaryOp op = /* ... */;
        Node* right = parsePrimaryExpr();
        left = new BinaryExpr(op, left, right);
    }
    return left;
}

This works but is fragile (manual delete, exception safety) I’d like to convert this to use std::unique_ptr everywhere in C++17.

Question: Given this simplified AST, what is the idiomatic way in C++17 to: store child nodes as std::unique_ptr inside BinaryExpr, and implement parseAdditiveExpr() so it builds the tree safely without leaks?

c++ compiler-construction