You could define a TVisitor
class template as done below:
#include <type_traits>
class Node;
class CompoundNode;
class Leaf;
template<bool isNonConstVisitor>
class TVisitor
{
typedef typename std::conditional<isNonConstVisitor,
Node, Node const>::type node_type;
typedef typename std::conditional<isNonConstVisitor,
CompoundNode, CompoundNode const>::type compound_node_type;
typedef typename std::conditional<isNonConstVisitor,
Leaf, Leaf const>::type leaf_node_type;
protected:
virtual void processNode(node_type& node) = 0;
public:
void visitLeaf(leaf_node_type& leaf) { processNode(leaf); }
void visitCompoundNode(compound_node_type& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children) { child->accept(*this); }
}
};
And then use Visitor
and ConstVisitor
as type aliases for corresponding instantiations of that class template:
typedef TVisitor<true> Visitor;
typedef TVisitor<false> ConstVisitor;