В моем моем предыдущем вопросе было высказано предположение, что производительность моего синтаксического анализатора boost::spirit::x3
можно улучшить, разобрав его в boost::string_view
с помощью директивы raw
.
Однако у меня возникают трудности с его компиляцией. Вот что я узнал:
До
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;
}
Однако он не компилируется:
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
? Как я могу убедиться, что моя перегрузка выбрана независимо от порядка включения?
directive/raw.hpp
было изменено на это: см. здесь @строка 42-44, тогда можно было бы использовать ADL, а перегрузка находилась бы вnamespace boost
- person m.s.   schedule 30.08.2016