A very brief intro. using v = std::variant<int, std::string, bool, std::list<int>>; v var{std::string(”foo”)}; std::get<std::string>(v) = ”bar”; Access the std::string and assign it a new value
v...) Matt Kline ”std::visit is everything wrong with modern C++” https://bitbashing.io/std-visit.html visitor visitor_obj; int i = std::visit(visitor_obj, variant_var);
v...) class visitor { public: int operator()(std::string) { /* str things */ } int operator()(int) { /* int things */ } int operator()(auto) { /* other things */ } }; visitor visitor_obj; int i = std::visit(visitor_obj, variant_var);
visitor { public: int operator()(std::string) { /* str things */ } int operator()(int) { /* int things */ } int operator()(auto) { /* other things */ } }; visitor visitor_obj; int i = std::visit(visitor_obj, variant_var); std::visit(func_obj, v...) • Uncool! Implementation far away from use.
visitor { public: int operator()(std::string) { /* str things */ } int operator()(int) { /* int things */ } int operator()(auto) { /* other things */ } }; visitor visitor_obj; int i = std::visit(visitor_obj, variant_var); std::visit(func_obj, v...) • Uncool! Implementation far away from use. • A lambda is an object of class type with operator()
visitor { public: int operator()(std::string) { /* str things */ } int operator()(int) { /* int things */ } int operator()(auto) { /* other things */ } }; visitor visitor_obj; int i = std::visit(visitor_obj, variant_var); std::visit(func_obj, v...) • Uncool! Implementation far away from use. • A lambda is an object of class type with operator() • A lambda can be a base class
visitor { public: int operator()(std::string) { /* str things */ } int operator()(int) { /* int things */ } int operator()(auto) { /* other things */ } }; visitor visitor_obj; int i = std::visit(visitor_obj, variant_var); std::visit(func_obj, v...) • Uncool! Implementation far away from use. • A lambda is an object of class type with operator() • A lambda can be a base class
template <typename ... T> class overload : T... { public: overload(T... t) : T(t)... {} using T::operator()...; }; auto x = overload( [](int) {}, [](std::string){} ); C++17 variadic using, to bring operator() from each T into view
using v = std::variant<int, std::string, bool, std::list<int>>; void func(v obj) { std::visit(overload( [](int) { /* int stuff */ }, [](std::string) { /* string stuff */ }, [](const auto&) { /* other stuff */ }), obj); } Now the logic is where we use it. Cool!
tokens Tokens for a very simple calculator. template <char> struct C {}; struct number { double value; }; struct ident { std::string_view value; }; struct eof {}; struct remember {}; struct forget {}; For single character tokens like + - * / (
tokens Tokens for a very simple calculator. template <char> struct C {}; struct number { double value; }; struct ident { std::string_view value; }; struct eof {}; struct remember {}; struct forget {}; Let numeric literals hold the value
tokens Tokens for a very simple calculator. template <char> struct C {}; struct number { double value; }; struct ident { std::string_view value; }; struct eof {}; struct remember {}; struct forget {}; and for lexer errors an exception is thrown