2016-08-30 95 views
2

將std :: string解析爲boost :: string_view在我的my previous question中,有人建議我可以通過使用raw指令解析爲boost::string_view來提高我的boost::spirit::x3解析器的性能。使用boost :: spirit :: x3

但是,我很難得到它編譯。 這是我發現:

  • 之前,一個有專攻assign_to_attribute_from_iterators(見例如this SO answer)來處理raw指令。

  • 現在使用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; 
} 

live example

然而,編譯:

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))); 
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

live example

我怎樣才能從實例化一個std::string::const_iteratorboost::string_view

2)如果boost/spirit/home/x3.hpp包括之前move_to超載

live example

爲什麼沒有選擇我的過載?這不是比boost/spirit/home/x3/support/traits/move_to.hpp中定義的更好的超載嗎? 我怎樣才能確保我的超負荷是選擇無論順序包含?

+0

2)是偏序。我不認爲有解決方法(我以前沒有找到過) - 請參閱http://en.cppreference.com/w/cpp/language/partial_specialization#Partial_ordering – sehe

+0

@sehe我認爲這將有助於'directive/raw.hpp'改爲:[見這裏@ line 42-44](http://coliru.stacked-crooked.com/a/7eeab94a4474ff18),那麼可以使用ADL,並且重載將駐留在'命名空間提升' –

回答

2

我簡單的寫你想要什麼:

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

您可能要檢查存儲contiguous¹作爲一個概念檢查您輸入範圍。在這方面,它可能是更清楚還需要迭代器是隨機訪問,並寫:

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

¹這是string_view要求反正

+0

可以通過'Boost Concept Checking'完成概念檢查嗎? –

+0

我不明白爲什麼不,但我沒有使用它。 – sehe

相關問題