-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlambda_visitor.cpp
45 lines (32 loc) · 929 Bytes
/
lambda_visitor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <cassert>
#include <functional>
#include <algorithm>
#include <memory>
template <typename RV, typename... Ts>
struct Visitor {
Visitor(std::function<RV(const Ts&)>... args): ts { std::move(args)... } {}
template <typename T>
RV visit(const T& t) {
return std::get<std::function<RV(const T&)>>(ts)(t);
}
private:
std::tuple<std::function<RV(const Ts&)>...> ts;
};
using BaseVisitor = Visitor<void, struct A, struct B>;
struct Base {
virtual void accept(BaseVisitor& v) = 0;
};
struct A: public Base {
void accept(BaseVisitor& v) override { return v.visit(*this); }
};
struct B: public Base {
void accept(BaseVisitor& v) override { return v.visit(*this); }
};
int main() {
std::shared_ptr<Base> base_ptr = std::make_shared<A>();
std::string call;
auto v = BaseVisitor([&call](const A&){ call = "A"; }, [&call](const B&){ call = "B"; });
base_ptr->accept(v);
assert( call == "A" );
return 0;
}