For some of these, yes.  For others, less so.  Each one has their limitations.<p>For the AstVisitor, you could make a templated class AstVisitor&lt;T&gt;.  You would then derive AstVisitor&lt;BoolLiteral&gt; in order to have a class that only visits particular node types.<p><pre><code>    template&lt;typename T&gt;
    class AstVisitor : public GenericAstVisitor {
      &#x2F;&#x2F; Implements GenericAstVisitor::Visit
      virtual void Visit(AstNode* expr) {
        T* t_expr = dynamic_cast&lt;T*&gt;(expr);
        if(t_expr){
          Visit(t_expr);
        }
      }

      virtual void Visit(T* expr) = 0;
    };
</code></pre>
If you need to visit multiple node types, then you would need to head into variadic templates.  Here, you would inherit from AstVisitor&lt;BoolLiteral, NumLiteral&gt;, then implement a visitor for each type.<p><pre><code>    template&lt;typename... T&gt;
    class AstVisitor;

    template&lt;typename First, typename... Rest&gt;
    class AstVisitor&lt;First, Rest...&gt; : public AstVisitor&lt;Rest...&gt; {
      virtual void Visit(AstNode* expr) {
        First* f_expr = dynamic_cast&lt;First*&gt;(expr);
        if(f_expr){
          Visit(f_expr);
        } else {
          AstVisitor&lt;Rest...&gt;::Visit(expr);
        }
      }

      virtual void Visit(First* expr) = 0;
    };

    template&lt;&gt;
    class AstVisitor&lt;&gt; : GenericAstVisitor {
      virtual void Visit(AstNode*) { }
    };
</code></pre>
For the enums and switch statements, I don&#x27;t know of any way to get away from using macros.  There have been some proposals for C++17 to include compile-time reflection, but until then, we&#x27;re stuck with the macros.