I think I found a way to do this. (I donβt know, this is the best way, but it works ;-)). The problem was int & type, because boost :: variant contains int, not int &. Therefore, I am updating your template to accept two types: one for the getter option and one for the return type.
I updated the get_impl template as follows:
template <typename Result, typename Inner> struct get_impl { template <typename T> struct result { typedef Result type; }; template <BOOST_VARIANT_ENUM_PARAMS(typename T)> Result operator()(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> & v) const { return boost::get<Inner>(v); } };
And my grammar now looks like this:
typedef boost::variant<std::string,int> VariantType; qi::rule<DG_Iterator, void(VariantType&), DG_Skipper> rule1; ph::function<get_impl<int,int> > const get_int = get_impl<int, int>(); ph::function<get_impl<int&,int> > const get_int_ref = get_impl<int&,int>(); rule1 = qi::eps [ std::cout << ph::val("variant=") << qi::_r1 << ph::val("\n") ] >> qi::eps [ std::cout << ph::val("before=") << get_int(qi::_r1) << ph::val("\n") ] >> qi::eps [ get_int_ref(qi::_r1) = ph::val(7) ] >> qi::eps [ std::cout << ph::val("after=") << get_int(qi::_r1) << ph::val("\n") ] ; VariantType val(2134); TestSimpleRuleValidity("x",rule1( ph::ref(val) ), true); std::cout << val << "\n";
And everything seems to be working fine. Thank you again for your initial answer, which helps me a lot.
source share