【问题标题】:How do I convert boost::spirit::qi::lexeme's attribute to std::string?如何将 boost::spirit::qi::lexeme 的属性转换为 std::string?
【发布时间】:2015-08-27 08:57:02
【问题描述】:

考虑:

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    在您的情况下,您可能可以使用as_string[]。但您也可以修正参数以采用std::vector&lt;char&gt; const&amp;


    最后你可以使用attr_cast&lt;&gt; 来达到与单独的qi::rule&lt;&gt; 完全相同的效果(但不使用单独的规则:))但我不推荐它以提高效率和因为旧版本的 boost 在这个工具中存在错误。

    【讨论】:

    • as_string 似乎正是我想要的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多