Search code examples
c++templatesvirtualvisitor-pattern

need a virtual template member workaround


I need to write a program implementing the visitor design pattern. The problem is that the base visitor class is a template class. This means that BaseVisited::accept() takes a template class as a parameter and since it uses 'this' and i need 'this' to point to the correct runtime instance of the object, it also needs to be virtual.
I'd like to know if there's any way around this problem.

template <typename T>
class BaseVisitor {
  public:
    BaseVisitor();
    T visit(BaseVisited *visited);
    virtual ~BaseVisitor();
}


class BaseVisited {
  BaseVisited();
  template <typename T>
    virtual void accept(BaseVisitor<T> *visitor) { visitor->visit(this); }; // problem
  virtual ~BaseVisited();
}

Solution

  • What you should do is separate the BaseVisitor.

    class BaseVisited;
    class BaseVisitorInternal {
    public:
        virtual void visit(BaseVisited*) = 0;
        virtual ~BaseVisitorInternal() {}
    };
    class BaseVisited {
        BaseVisited();
        virtual void accept(BaseVisitorInternal* visitor) { visitor->visit(this); }
    };
    template<typename T> class BaseVisitor : public BaseVisitorInternal {
        void visit(BaseVisited* visited);
    };
    

    If you need BaseVisited's derived classes to be templated too AND pass their correct types/overloads to visit, you're officially dead.