Skip to content

Instantly share code, notes, and snippets.

@PiJoules
Created August 2, 2017 18:54
Show Gist options
  • Save PiJoules/f4fa713fc697b0412e3fff8a0eeb9e0a to your computer and use it in GitHub Desktop.
Save PiJoules/f4fa713fc697b0412e3fff8a0eeb9e0a to your computer and use it in GitHub Desktop.
Visitor design pattern using templates for abstract visitor and visitable
#include <iostream>
#include <vector>
/******* Lib start *****/
class BaseVisitor {
public:
virtual ~BaseVisitor(){}
};
class BaseVisitable {
public:
virtual void* accept(BaseVisitor&) = 0;
};
template <typename Visitable>
class Visitor {
public:
virtual void* visit(Visitable&) = 0;
};
template <typename DerivedVisitable>
class Visitable: public BaseVisitable {
public:
void* accept(BaseVisitor& base_visitor){
Visitor<DerivedVisitable>& visitor = dynamic_cast<Visitor<DerivedVisitable>&>(base_visitor);
return visitor.visit(static_cast<DerivedVisitable&>(*this));
}
};
/******* Lib end *****/
/******* Impl start *******/
class Visitable1 : public Visitable<Visitable1> {
// Custom V1 logic
};
class Visitable2 : public Visitable<Visitable2> {
// Custom V2 logic
};
class VisitorDerived : public BaseVisitor,
public Visitor<Visitable1>,
public Visitor<Visitable2>
{
public:
void* visit(Visitable1& c){
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void* visit(Visitable2& c){
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
/*********** Impl end ********/
int main(){
VisitorDerived visitor;
Visitable1 visitable1;
Visitable2 visitable2;
std::vector<BaseVisitable*> v = {&visitable2, &visitable1};
for (BaseVisitable* visitable : v){
visitable->accept(visitor);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment