在我的my previous question中,建议通过使用boost::spirit::x3
指令解析为boost::string_view
来提高raw
解析器的性能。
但是,我很难编译它。 这就是我发现的:
在x3
之前,必须专门设置assign_to_attribute_from_iterators
(请参阅例如this SO answer)来处理raw
指令。
x3
现在使用move_to
免费功能(请参阅例如this SO answer)。
因此我添加了一个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;
}
然而,不编译:
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)));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何从boost::string_view
实例化std::string::const_iterator
?
2)如果在boost/spirit/home/x3.hpp
重载之前包含move_to
为什么我的超载没有被选中?它不是比boost/spirit/home/x3/support/traits/move_to.hpp
中定义的任何更好的超载吗?
无论包含顺序如何,我如何确保选择过载?
答案 0 :(得分:2)
我只是写下你想要的东西:
v = boost::string_view(&*b, std::distance(b,e));
您可能希望检查存储是否为连续¹作为输入范围的概念检查。在这方面,也可以更清楚地要求迭代器是随机访问,并写:
v = boost::string_view(&*b, e-b);
¹这是string_view的要求