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

7

请考虑:

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

...还有一个带有属性 AttrType 的规则 r

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个回答

4
您可以使用qi::as_string[](如果存在合适的自动转换,它将把属性强制转换为字符串)。
或者您可以使用qi::raw[],它公开源迭代器范围。这将自动转换为std::string属性。好处在于输入可以不经过更改地反映出来(例如,qi::raw[qi::int_>>';'>>qi::double_]将起作用。
在您的情况下,您可能可以使用as_string[]。但您也可以修复参数以接受std::vector<char> const& 最后,您可以使用attr_cast<>实现与单独的qi::rule<>完全相同的效果(但不使用单独的规则:)),但我不建议出于效率和因为旧版本的boost中存在此设施的错误。

as_string 看起来正是我想要的。谢谢! - Braden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接