代码之家  ›  专栏  ›  技术社区  ›  Quentin

Simple Spirit X3分词器无法编译,属性不匹配

  •  1
  • Quentin  · 技术社区  · 8 年前

    #include <string>
    #include <vector>
    #include <boost/spirit/home/x3.hpp>
    
    int main() {
        namespace x3 = boost::spirit::x3;
    
        std::wstring const str = L"bonjour je suis un  petit panda";
    
        auto word = x3::lexeme[+x3::alpha];
    
        std::wstring s;
        x3::phrase_parse(begin(str), end(str), word, x3::space, s); // OK
    
        std::vector<std::wstring> v;
        x3::phrase_parse(begin(str), end(str), *word, x3::space, v); // Compiler error
    }
    

    Live demo on Coliru

    这个错误非常复杂,但归根结底是无法调用 move_to ,这是属性类型不匹配的症状。

    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:180:9: error: no matching function for call to 'move_to'
            detail::move_to(std::move(src), dest
            ^~~~~~~~~~~~~~~
    
    [...]
    
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:56:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::unused_attribute' for 3rd argument
            move_to(Source&&, Dest&, unused_attribute) {}
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:74:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::plain_attribute' for 3rd argument
            move_to(Source&& src, Dest& dest, plain_attribute)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:97:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::tuple_attribute' for 3rd argument
            move_to(Source&& src, Dest& dest, tuple_attribute)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:106:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::tuple_attribute' for 3rd argument
            move_to(Source&& src, Dest& dest, tuple_attribute)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:150:9: note: candidate function not viable: no known conversion from 'typename attribute_category<basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > >::type' (aka 'boost::spirit::x3::traits::container_attribute') to 'boost::spirit::x3::traits::variant_attribute' for 3rd argument
            move_to(Source&& src, Dest& dest, variant_attribute tag)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:85:35: note: candidate template ignored: disabled by 'enable_if' [with Source = const wchar_t, Dest = std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >]
            inline typename enable_if<is_container<Source>>::type
                                      ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:113:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
            move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:143:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
            move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:157:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
            move_to(Iterator, Iterator, unused_type, unused_attribute) {}
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:161:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
            move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
            ^
    /usr/local/include/boost/spirit/home/x3/support/traits/move_to.hpp:171:9: note: candidate function template not viable: requires 4 arguments, but 3 were provided
            move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, container_attribute)
            ^
    

    word std::string 一如预期。为什么不呢 *word std::vector<std::string> ,那我该写什么呢?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Nikita Kniazev    8 年前

    您正在使用ASCII版本的字符分析器( x3::alpha 是的同义词 x3::standard::alpha ),传递的迭代器值类型为 wchar_t ,但是 boost::spirit::char_encoding::standard::ischar() 对于非ascii字符返回false。

    x3::standard_wide::alpha 它的工作原理是:

    #include <string>
    #include <vector>
    #include <boost/spirit/home/x3.hpp>
    
    int main() {
        namespace x3 = boost::spirit::x3;
    
        std::wstring const str = L"bonjour je suis un  petit panda";
    
        auto word = x3::lexeme[+x3::standard_wide::alpha];
    
        std::wstring s;
        x3::phrase_parse(begin(str), end(str), word, x3::space, s); // OK
    
        std::vector<std::wstring> v;
        x3::phrase_parse(begin(str), end(str), *word, x3::space, v); // OK
    }
    

    x3::standard::space 和 x3::standard_wide::space