Я думаю, что нашел способ, как это сделать. (Не знаю, если это лучший способ, но это работает ;-)).
Проблема была в int & type, потому что boost :: variable содержит int, а не int &. Поэтому я обновляю ваш шаблон, чтобы принимать два типа: один для варианта получения и один для типа возврата.
Я обновил get_impl шаблон таким образом:
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);
}
};
И моя грамматика теперь выглядит так:
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";
И все, кажется, работает хорошо. Еще раз спасибо hkaiser за ваш первоначальный ответ, который мне очень помогает.