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

How do I convert boost::spirit::qi::lexeme's attribute to std::string?

本文关键字:属性 转换 std string lexeme boost spirit qi      更新时间:2023-10-16

考虑:

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_('_'))];

。但这似乎有点尴尬。 有没有更好的方法?

您可以使用

qi::as_string[](如果存在合适的自动转换,则会将属性强制转换为字符串)。

或者,您可以使用公开源迭代器范围的qi::raw[]。这将自动转换为std::string属性。这里的好处是输入可以原封不动地反映(例如 qi::raw[ qi::int_ >> ';' >> qi::double_ ]将起作用

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


最后,您可以使用attr_cast<>来实现与单独qi::rule<>完全相同的效果(但不使用单独的规则:)),但我不建议这样做是为了提高效率,因为旧版本的 boost 在此功能中有错误。