在我的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<>或任何类似的方法来使用Phoenix访问boost::variant。我需要phoenix::get<>的原因是因为我需要将variant插入到具有特定类型的列表中,然后将此特定类型作为对子规则的引用作为继承属性进行传递:
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(')')
...有没有办法实现这样的行为呢?
感谢您的回复
瑞克
发布于 2011-02-22 20:34:25
编写自己的“懒惰”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) ]发布于 2011-02-22 22:15:48
我想我找到了一种方法。(不知道这是不是最好的方法,但它可以工作;-) )。问题出在int& type中,因为boost::variant包含int而不是int&。因此,我更新了您的模板以接受两种类型,一种用于变量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";一切似乎都很正常。再次感谢您的初步答复,这对我很有帮助。
https://stackoverflow.com/questions/5077037
复制相似问题