Skip to content

Instantly share code, notes, and snippets.

@dkorolev
Last active August 29, 2015 14:19
Show Gist options
  • Save dkorolev/37399bb458fffab23065 to your computer and use it in GitHub Desktop.
Save dkorolev/37399bb458fffab23065 to your computer and use it in GitHub Desktop.
// V1: Types `A` and `B` hardcoded.
#include <cstdio>
#include <memory>
// Library code.
struct A;
struct B;
struct VisitorBase {
virtual void Visit(A&) {
printf("This should never happen (`VisitorBase::Visit(A&)`)!\n");
}
virtual void Visit(B&) {
printf("This should never happen (`VisitorBase::Visit(B&)`)!\n");
}
};
struct GenerallyVisitable {
virtual void Accept(VisitorBase&) {
printf("This should never happen (`GenerallyVisitable::Accept(VisitorBase&);`).\n");
}
};
template<typename T> struct Visitable : GenerallyVisitable {
virtual void Accept(VisitorBase& v) override {
v.Visit(*reinterpret_cast<T*>(this));
}
};
// User simple code (defining visitable classes, with non-virtual methods).
struct A : Visitable<A> {
void foo() {
printf("A::foo()\n");
}
};
struct B : Visitable<B> {
void bar() {
printf("B::bar()\n");
}
};
// User complex code (making use of non-virtual methods of visitable classes).
int main() {
std::unique_ptr<GenerallyVisitable> pa(new A());
std::unique_ptr<GenerallyVisitable> pb(new B());
struct FooOrBarCaller : VisitorBase {
virtual void Visit(A& a) override {
a.foo();
}
virtual void Visit(B& b) override {
b.bar();
}
} visitor;
pa->Accept(visitor);
pb->Accept(visitor);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment