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();
}
What you should do is separate the BaseVisitor.
If you need BaseVisited's derived classes to be templated too AND pass their correct types/overloads to visit, you're officially dead.
I came up with something slightly different than DeadMG:
Mine has an extra
result()
member function that lets you retrieve the result of the last visit.You cannot declare/define templated virtual functions. The reason is that the virtual dispatch mechanism must be known when the compiler sees the base class definition, but templates are compiled on demand.
With the common vtable implementation the issue is that the number of entries that the compiler would have to reserve for the virtual function is undefined (how many different instantiations of the type can there be?), as is the order of them. If you declare the class:
The compiler can reserve two entries in the vtable for the pointers to
foo
andbar
in the vtable, and the vtable is perfectly defined by just inspecting the class definition. This cannot be achieved with templated functions.