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 46 47 48 49 50 51 52 53 54 55 56
| #include <cstdint> #include <iostream> #include <string> #include <variant>
struct UserEvent { struct Login { std::string username; }; struct Signoff {}; struct Query { uint32_t item_id{}; }; struct Click { int32_t x{}; int32_t y{}; };
std::variant<std::monostate, Login, Signoff, Query, Click> event; };
template <typename... Ts> struct Overloaded : Ts... { using Ts::operator()...; };
template <typename... Ts> Overloaded(Ts...) -> Overloaded<Ts...>;
template <typename E, typename O> constexpr auto visit(const E& e, O&& o) { return std::visit(std::forward<O>(o), e.event); }
template <typename E, typename... Ts> constexpr auto match(const E& e, Ts&&... ts) { return std::visit(Overloaded<std::decay_t<Ts>...>{std::forward<Ts>(ts)...}, e.event); }
int main() { auto visitor = Overloaded{[](const UserEvent::Login& login) { std::cout << "User logged in: " << login.username << "\n"; }, [](const UserEvent::Signoff&) { std::cout << "User signed off\n"; }, [](const auto&) {}}; visit(UserEvent{UserEvent::Login{"Alice"}}, visitor); visit(UserEvent{UserEvent::Signoff{}}, visitor);
auto event = UserEvent{UserEvent::Click{.x = 10, .y = 20}}; match( event, [](const UserEvent::Click& click) { std::cout << "Clicked " << click.x << ", " << click.y << "\n"; }, [](const auto&) {}); }
|