使用boost::spirit::x3从std::string解析为boost::string_view

parsing from std::string into a boost::string_view using boost::spirit::x3

本文关键字:string boost view std spirit x3 使用      更新时间:2023-10-16

在我之前的问题中,有人建议我的boost::spirit::x3解析器的性能可以通过使用raw指令解析成boost::string_view来提高。

然而,我很难让它编译。这是我发现的:

  • x3之前,必须专门化assign_to_attribute_from_iterators(参见例如这个SO答案)来处理raw指令。

  • x3现在使用move_to free函数代替(参见例如这个SO答案)。

因此,我添加了一个move_to重载,如果我从char*解析:

#include <iostream>
#include <string>
#include <boost/utility/string_view.hpp>
namespace boost {
namespace spirit { namespace x3 { namespace traits {
template <typename It>
void move_to(It b, It e, boost::string_view& v)
{
    v = boost::string_view(b, std::size_t(std::distance(b,e)));
}
} } }
} // namespace boost
#include <boost/spirit/home/x3.hpp>
namespace parser
{
    namespace x3 = boost::spirit::x3;
    using x3::char_;
    using x3::raw;
    const auto str  = raw[ +~char_('_')] >> '_';
}
int main()
{
    std::string input = "hello world_";
    boost::string_view str; 
    parse(input.data(), input.data()+input.size(), parser::str, str);
    std::cout << str;
}
<<p> 生活例子/strong>

但是,它编译:

1)如果我使用std::string::const_iterator

解析
parse(input.cbegin(), input.cend(), parser::str, str);

boost::string_view的构造函数需要const char*std::string&

main.cpp:12:16: error: no matching function for call to 'boost::basic_string_view<char, std::char_traits<char> >::basic_string_view(__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, std::size_t)'
     v = boost::string_view(b, std::size_t(std::distance(b,e)));
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

生活例子

如何从std::string::const_iterator实例化boost::string_view ?

2)如果boost/spirit/home/x3.hppmove_to过载之前包含

生活例子

为什么没有选择我的过载?它不是比boost/spirit/home/x3/support/traits/move_to.hpp中定义的任何重载都更好吗?无论包含的顺序如何,我如何确保重载被选中?

我只是写你想要的:

v = boost::string_view(&*b, std::distance(b,e));

您可能想要检查存储是否连续¹作为输入范围的概念检查。在这方面,还要求迭代器是随机访问的,并写:

v = boost::string_view(&*b, e-b);

¹这是string_view的要求

相关文章: