The C++17 equivalent would be something like the following (not tested):
using NumberExpr = int;
using VarExpr = std::string;
struct AddExpr;
using Expr = std::variant<NumberExpr, AddExpr, VarExpr>;
struct AddExpr {
std::unique_ptr<Expr> a;
std::unique_ptr<Expr> b;
}
Of course, this being C++, you need forward declarations and a firm grasp of the rules of incomplete types to be confident about declaring a simple AST type.