Attuazione del visitor pattern utilizzando i Modelli C++
Ho cercato di ridurre la quantità di standard nel mio codice, utilizzando dei Template C++ per implementare il visitor pattern. Finora mi è venuta in mente questa:
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));
}
};
E ogni sottoclasse di Visitabili assomiglia a questo:
class Mesh : public Object, public Visitable<Mesh> {};
class Text : public Object, public Visitable<Text> {};
E, infine, il Visitatore sembra questo:
class Renderer : public Visitor<Mesh>, public Visitor<Text> {}
Finora tutto bene… ora ecco il 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);
}
}
Devo in qualche modo il cast Visitabile in modo che io possa chiamare accept(), ma ovviamente non so cosa T è. In alternativa, posso aggiungere un virtual accept() per la Visitabile modello, perché non so che argomento si dovrebbe prendere.
Qualsiasi C++ Template guru là fuori sa come fare questo lavoro?
- Qui è attualmente il modo moderno di fare è: visita-senza-viaggi.
Questo può essere fatto in C++11 utilizzo di modelli variadic. Proseguendo da Pete risposta:
Sottoclassi di
Visitable
:Un
Visitor
sottoclasse:Non è chiaro qual è il
value_type
del vostroScene
contenitore, ma è necessario per ottenere un riferimento o puntatore aVisitable<Mesh, Text>
su cui chiamareaccept
:Visitor
supporta tutte le classi specificate nelVisitableImpl
specializzazione nell’ordine esatto, non è vero?Tuo BaseVisitor non fa nulla per voi, altro che arbitrario visitees per eliminare il visitatore. Invece, si desidera avere una classe base per il visitatore, che fornisce tutti dei diversi
accept
funzioni che potrebbe essere chiamato su di esso, e per laVisitable
accettare questo visitatore.Per fare questo, si potrebbe utilizzare un nell’elenco tipo per definire i tipi, il visitatore può accettare, avere una base visitee di classe, che prende il tipo di elenco e aggiungere il tipo di elenco parametro visitee attuazione.
sketch di esempio:
Ho anche bisogno di un basato su modelli Visitor pattern, e stato in grado di creare una soluzione che non comporta l’utilizzo di variadic o di tipi di tipo di liste.
Dopo le interfacce sopra definiti, creare interfacce specifiche per un visitabile oggetto del visitatore, quindi implementare nella propria classe di calcestruzzo:
Si potrebbe anche saltare il visitatore interfacce di tutto e avere il vostro concreto visitatore derivare da
OfType<Derived, SomeClass>
direttamente, ma trovo che usare il primo è migliore per estendere il visitatore come nuove classi sono definite (That
deve preoccuparsi che le visite per tutto il tempo che è di tipoThatVisitor
).