以前写个过一篇博客叫《浅谈boost.variant的几种访问方式》,里面讲到了能够经过访问者方式来获取variant的值,可是在重载函数operator()
里面只可以获取variant的值,若是要捕获外部变量或调用外部函数比较麻烦,那么有没有一种方法来简化variant的访问呢?固然有,下面咱们让variant支持lambda表达式访问(我的博客也发表了《让boost.variant支持lambda表达式访问》)。ios
#include <iostream> #include <string> #include <utility> #include <type_traits> #include <boost/variant.hpp> template<typename Function, typename... Args> struct make_overload_impl : make_overload_impl<Function>::type, make_overload_impl<Args...>::type { using type = make_overload_impl; using make_overload_impl<Function>::type::operator(); using make_overload_impl<Args...>::type::operator(); constexpr explicit make_overload_impl(Function&& func, Args&&... args) : make_overload_impl<Function>::type(std::forward<Function>(func)), make_overload_impl<Args...>::type(std::forward<Args>(args)...) {} }; template<typename Function> struct make_overload_impl<Function> { using type = Function; }; template<typename Return, typename... Args> struct make_overload_impl<Return(*)(Args...)> { using type = make_overload_impl; using Function = Return(*)(Args...); constexpr explicit make_overload_impl(const Function&& func) : _func(func) {} constexpr Return operator()(Args&&... args) const { return _func(std::forward<Args>(args)...); } private: Function _func; }; struct make_overload { template<typename... Function, typename Overload = typename make_overload_impl<typename std::decay<Function>::type...>::type> constexpr Overload operator()(Function&&... func) const { return Overload(std::forward<Function>(func)...); } }; template<typename... Args> auto make_visitor(Args&&... args) { return make_overload()(std::forward<Args>(args)...); } int main() { auto visitor = make_visitor ( [](int& i) { std::cout << i << std::endl; }, [](std::string& i) { std::cout << i << std::endl; } ); boost::variant<int, std::string> v; v = "Hello world"; boost::apply_visitor(visitor, v); v = 100; boost::apply_visitor(visitor, v); return 0; }
该代码也上传到了个人github。git