以前寫個過一篇博客叫《淺談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