He estado tratando de reducir la cantidad de repetición en mi código, mediante el uso de plantillas de C++ para implementar el patrón de visitante. Hasta ahora me he llegado con esto:Implementando el patrón de visitante usando las plantillas de C++
class BaseVisitor {
public:
virtual ~BaseVisitor() {}
};
template<typename T>
class Visitor : public BaseVisitor {
public:
virtual void visit(T& /* visitable */) = 0;
};
template<typename Derived>
class Visitable {
public:
void accept(Visitor<Derived>& visitor) {
visitor.visit(static_cast<Derived&>(*this));
}
};
Y cada subclase de Visitable se ve así:
class Mesh : public Object, public Visitable<Mesh> {};
class Text : public Object, public Visitable<Text> {};
Y, finalmente, el visitante se ve así:
class Renderer : public Visitor<Mesh>, public Visitor<Text> {}
hasta el momento tan bueno ... ahora aquí está el problema:
for(Scene::iterator it = scene.begin(); it != scene.end(); ++it) {
Object& object = static_cast<Object&>(*it);
if(pre_visit(object)) {
object.accept(this); ///Erm, what do I cast to??
post_visit(object);
}
}
Necesito de alguna manera convertir a Visitable para que pueda llamar a accept(), pero obviamente no sé qué es T. Alternativamente, no puedo agregar un accept virtual() a la plantilla Visitable, porque no sé qué argumento debería tomar.
Cualquier gurú de las plantillas de C++ sabe cómo hacer que esto funcione?
Aquí es la forma en que actualmente moderna para hacerlo: [visitando-sin-itinerante] (https://backwardsincompatibilities.wordpress.com/2015/10/26/visiting-without-travelling/). – davidhigh