如何从Spirit :: Qi规则访问boost :: variant成员?

我无法找到一种正确的方法如何在我的Spirit-Qi语法中使用boost :: phoenix访问boost :: variant的成员。这是一个简单的例子,我正在努力实现。 (我的整个语法要复杂得多,这是我测试提到的问题的简单片段)。
namespace ph = boost::phoenix;
typedef boost::variant<std::string,int> VariantType;
typedef std::list<VariantType> TlstVariants;

rule<Iterator, void(TlstVariants&), Skipper>    rule1;

rule1 = 
   qi::eps [ ph::push_back(qi::_r1, ph::construct<int>(2)) ]
>> qi::eps [ ph::get<int>(ph::back(qi::_r1)) = ph::val(3) ] //THIS IS EXAMPLE OF WHAT I NEED
;

TlstVariants lstVals;
ExecuteParser("5",rule1( ph::ref(lstVals) ));   

BOOST_FOREACH( VariantType &val, lstVals )
{
    std::cout << val.which() << " - " << val;
}
但我找不到任何phoenix :: get&lt;>或任何类似的方法来使用Phoenix访问boost :: variant。我需要phoenix :: get&lt;>的原因是因为我需要将变量插入到具有特定类型的列表中,然后将此特定类型作为对子规则的引用作为继承属性传递:
qi::rule<Iterator, void(structTest&), Skipper> rule_child;

rule = 
  qi::lit("test") [ph::push_back(sp::_r1, ph::construct<structTest>())]
> qi::lit('(') 
> rule_child( ph::get<structTest>(ph::back(sp::_r1)) ) 
> qi::lit(')') 
...
有没有办法如何实现这样的行为? 谢谢你的回复 干草堆     
已邀请:
编写自己的'懒惰'Phoenix函数相当容易。这是
boost::variant
的一个。
#include <boost/variant.hpp>
#include <boost/spirit/include/phoenix.hpp>

template <typename Result>
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)> const& v) const
    {
        return boost::get<Result>(v);
    }
};

ph::function<get_impl<int> > const get_int = get_impl<int>();
现在,这可以用于语义操作:
... qi::eps [ get_int(ph::back(qi::_r1)) = ph::val(3) ]
    
我想我找到了一种方法。 (不知道这是否是最佳方式,但它有效;-))。 问题出在int&amp; type,因为boost :: variant包含int而不是int&amp ;.所以我更新你的模板以接受两种类型,一种用于变体getter,一种用于返回类型。 我用这种方式更新了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的初步回复,这对我很有帮助。     

要回复问题请先登录注册