如何将boost :: spirit :: qi :: lexeme属性转换为std :: string?

时间:2015-06-11 15:06:02

标签: c++ boost boost-spirit boost-spirit-qi boost-phoenix

考虑:

struct s {
  AttrType f(const std::string &);
};

...以及具有属性r的规则AttrType

template <typename Signature> using rule_t =
  boost::spirit::qi::rule<Iterator,
                          Signature,
                          boost::spirit::qi::standard::space_type>;

rule_t<AttrType()> r;

r = lexeme[alnum >> +(alnum | char_('.') | char_('_'))][
      _val = boost::phoenix::bind(&s::f, s_inst, _1)
    ];

编译时(使用clang),我收到以下错误消息:

boost/phoenix/bind/detail/preprocessed/member_function_ptr_10.hpp:28:72: error: no viable conversion from
      'boost::fusion::vector2<char, std::__1::vector<char, std::__1::allocator<char> > >' to 'const std::__1::basic_string<char>'
                return (BOOST_PROTO_GET_POINTER(class_type, obj)->*fp)(a0);
                                                                       ^~

我的印象是问题是占位符变量的类型_1。有没有简洁的方法将lexeme的属性转换为std::string用于此目的?

如果我插入属性类型为std::string的其他规则,则会编译:

rule_t<std::string()> r_str;

r = r_str[boost::phoenix::bind(&s::f, s_inst, _1)];
r_str = lexeme[alnum >> +(alnum | char_('.') | char_('_'))];

......但这看起来有点尴尬。还有更好的方法吗?

1 个答案:

答案 0 :(得分:4)

您可以使用qi::as_string[](如果存在合适的自动转换,属性强制转换为字符串。)

或者,您可以使用qi::raw[]来公开source-iterator范围。这将自动转换为std::string属性。这里的好处是输入可以不加改变地反映(例如qi::raw[ qi::int_ >> ';' >> qi::double_ ]将起作用

在您的情况下,您可以使用as_string[]。但您也可以修改参数以获取std::vector<char> const&

最后,您可以使用attr_cast<>来实现与单独的qi::rule<>完全相同的效果(但不使用单独的规则:))但是我不会&#39;为了提高效率而推荐它,因为旧版本的boost在这个设施中存在缺陷。