When traversing the tree, I think you'll need at least one branch/virtual method dispatch to determine the type of the child node.
Given that, you could create a templated subclass for each type in the grammar, then instantiate it with the number of children. Eg:
template<N> class Node : TODO { type 'N'; int const count N; Node a[N]; }
Allocating Node<2> is a single malloc. You can add static asserts to get things like Node<4> to fail at compile time, change the c style array to std::array<Node, N> to get bounds checks, and so on.
At that point, you can get arbitrarily fancy with custom allocators, inlining the type to be stored in the tree, etc.
[edit: Note that my solution kinda sucks, because you need to pay for a virtual method dispatch to run code that has N compiled in, and I also rolled my own reflection with instance variables, so I'm bloating each node by two words instead of one, and also breaking constant propagation in the caller code.
Removing the implicit vtable or the extra instance variables is an exercise left to the reader.]