【问题标题】:boost locale incomplete type boundary_indexing<char32_t>提升语言环境不完整类型边界索引<char32_t>
【发布时间】:2018-07-25 04:32:48
【问题描述】:

我首先将一个 utf-8 字符串转换为 utf-32,然后我希望将唯一的单词与它们的位置进行映射。我从 boost 语言环境开始。

#include <iostream>
#include <string>
#include <chrono>
#include <boost/shared_ptr.hpp>
#include <map>
#include <list>
#include <boost/locale.hpp>

typedef std::u32string string_type;
typedef std::pair<unsigned long, unsigned long> range_type;
typedef std::map<std::string, std::list<range_type>> wordref_type;

struct parser{
    /**
     * returns a map of "words" with its positions list
     */
    static wordref_type parse(string_type::const_iterator b, string_type::const_iterator e){
        wordref_type wordrefs;
        range_type sentence;

        boost::locale::boundary::segment_index<string_type::const_iterator> index(boost::locale::boundary::word, b, e);
        //TODO: iterate index
        return wordrefs;
    }
};

int main(int argc, char** argv){
    std::string input_str = "Some UTF-8 texts";
    string_type buffer = boost::locale::conv::utf_to_utf<string_type::value_type>(input_str); // convert utf-8 to utf-32
    wordref_type wordrefs = parser::parse(buffer.cbegin(), buffer.cend());
    return 0;
}

它抱怨invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing&lt;char32_t&gt;’。怎么了 ?我已经Ideone'ed 了

In file included from /usr/include/boost/locale/boundary.hpp:15:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/index.hpp: In instantiation of ‘static boost::locale::boundary::index_type boost::locale::boundary::details::mapping_traits<IteratorType, std::random_access_iterator_tag>::map(boost::locale::boundary::boundary_type, IteratorType, IteratorType, const std::locale&) [with IteratorType = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::index_type = std::vector<boost::locale::boundary::break_info>]’:
/usr/include/boost/locale/boundary/index.hpp:126:83:   required from ‘boost::locale::boundary::details::mapping<BaseIterator>::mapping(boost::locale::boundary::boundary_type, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::details::mapping<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
/usr/include/boost/locale/boundary/index.hpp:631:43:   required from ‘boost::locale::boundary::segment_index<BaseIterator>::segment_index(boost::locale::boundary::boundary_type, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::segment_index<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
prog.cpp:21:118:   required from here
/usr/include/boost/locale/boundary/index.hpp:98:93: error: invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing<char32_t>’
                             index_type tmp=std::use_facet<boundary_indexing<char_type> >(l).map(t,begin,end);
                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/boost/locale/boundary.hpp:12:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/facets.hpp:90:19: note: declaration of ‘class boost::locale::boundary::boundary_indexing<char32_t>’
             class boundary_indexing;
                   ^~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/locale/boundary.hpp:15:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/index.hpp:103:95: error: invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing<char32_t>’
                             index_type tmp = std::use_facet<boundary_indexing<char_type> >(l).map(t,str.c_str(),str.c_str()+str.size());
                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/boost/locale/boundary.hpp:12:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/facets.hpp:90:19: note: declaration of ‘class boost::locale::boundary::boundary_indexing<char32_t>’
             class boundary_indexing;
                   ^~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/6/bits/locale_classes.h:850:0,
                 from /usr/include/c++/6/bits/ios_base.h:41,
                 from /usr/include/c++/6/ios:42,
                 from /usr/include/c++/6/ostream:38,
                 from /usr/include/c++/6/iostream:39,
                 from prog.cpp:1:
/usr/include/c++/6/bits/locale_classes.tcc: In instantiation of ‘const _Facet& std::use_facet(const std::locale&) [with _Facet = boost::locale::boundary::boundary_indexing<char32_t>]’:
/usr/include/boost/locale/boundary/index.hpp:98:89:   required from ‘static boost::locale::boundary::index_type boost::locale::boundary::details::mapping_traits<IteratorType, std::random_access_iterator_tag>::map(boost::locale::boundary::boundary_type, IteratorType, IteratorType, const std::locale&) [with IteratorType = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::index_type = std::vector<boost::locale::boundary::break_info>]’
/usr/include/boost/locale/boundary/index.hpp:126:83:   required from ‘boost::locale::boundary::details::mapping<BaseIterator>::mapping(boost::locale::boundary::boundary_type, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::details::mapping<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
/usr/include/boost/locale/boundary/index.hpp:631:43:   required from ‘boost::locale::boundary::segment_index<BaseIterator>::segment_index(boost::locale::boundary::boundary_type, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::segment_index<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
prog.cpp:21:118:   required from here
/usr/include/c++/6/bits/locale_classes.tcc:134:37: error: incomplete type ‘boost::locale::boundary::boundary_indexing<char32_t>’ used in nested name specifier
       const size_t __i = _Facet::id._M_id();


                ~~~~~~~~~~~^~~~~

【问题讨论】:

    标签: c++ boost locale utf utf-32


    【解决方案1】:

    您需要使用 BOOST_LOCALE_ENABLE_CHAR32_T 编译 boost 以包含 boundary_indexing&lt;char32_t&gt; 但是...

    Status of C++11 char16_t/char32_t support

    对 C++11 char16_tchar32_t 的支持是实验性的,大多数情况下都不起作用,也不打算在当前最新的编译器中用于生产 : GCC-4.5, MSVC10 直到修复主要编译器的缺陷。

    [....]

    如果您想构建或测试支持 C++11 char16_t 和 char32_t 的 Boost.Locale,您应该在构建期间将 cxxflags="-DBOOST_LOCALE_ENABLE_CHAR32_T -DBOOST_LOCALE_ENABLE_CHAR16_T" 传递给 b2,并在使用 Boost.Locale 时定义 BOOST_LOCALE_ENABLE_CHAR32_TBOOST_LOCALE_ENABLE_CHAR32_T

    [强调我的]

    http://www.boost.org/doc/libs/1_66_0/libs/locale/doc/html/facets_8hpp_source.html

    #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
    template<>
    class BOOST_LOCALE_DECL boundary_indexing<char32_t> : public std::locale::facet {
    

    【讨论】:

    • 现在我收到链接器错误Undefined symbols for architecture x86_64: "boost::locale::boundary::boundary_indexing&lt;char32_t&gt;::id", referenced。我在FIND_PACKAGE(Boost COMPONENTS filesystem regex locale REQUIRED) 中添加了语言环境
    • @NeelBasu 定义不够,还得用define编译
    • 但是我是通过brew安装的。如何使用支持 utf32 的 brew 重新安装它?
    • @NeelBasu 这是一个新问题。可能,更多关于其他网站的主题
    • 不确定,但您可以在安装 boost 之前尝试将定义导出到 cxxflags=-DBOOST_LOCALE_ENABLE_CHAR32_T。或者您可能需要修改 Boost.rb 并将定义添加到 args &lt;&lt; "cxxflags=
    【解决方案2】:

    它抱怨无效使用不完整类型'const class boost::locale::boundary::boundary_indexing' 怎么了?

    char32_t 不受支持。使用

    #define BOOST_LOCALE_ENABLE_CHAR32_T
    

    但是在构建库的过程中你也需要enable it

    对 C++0x char16_t 和 char32_t 字符串和流的实验性支持。

    进一步寻找:http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/status_of_cpp0x_characters_support.html

    如果您想构建或测试支持 C++11 char16_t 和 char32_t 的 Boost.Locale,您应该在构建期间将 cxxflags="-DBOOST_LOCALE_ENABLE_CHAR32_T -DBOOST_LOCALE_ENABLE_CHAR16_T" 传递给 b2,并在使用 Boost.Locale 时定义 BOOST_LOCALE_ENABLE_CHAR32_T 和 BOOST_LOCALE_ENABLE_CHAR32_T

    【讨论】:

    • 现在我收到链接器错误Undefined symbols for architecture x86_64: "boost::locale::boundary::boundary_indexing&lt;char32_t&gt;::id", referenced 但在我的 CMakeLists.txt 文件中我有FIND_PACKAGE(Boost COMPONENTS filesystem regex locale REQUIRED)。语言环境在那里。
    • 我不是刚刚把它放在我的答案中吗?库需要使用这些标志构建。
    • Headsup:在我的机器上,对 char32_t(很可能是语言环境方面)的标准库支持不足以构建实验性支持(即带有 gcc 5.x 或 gcc 7.x 的 Ubuntu 16.04 和相应的 libstdc++(也与 Clang5))。例如:paste.ubuntu.com/p/MpW5jwcfPh
    • 刚刚在 Ubuntu 18.04 (gcc 7.3, paste.ubuntu.com/p/6TmyHwHNNh) 上遇到了同样的情况
    猜你喜欢
    • 2012-07-18
    • 2019-01-15
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    相关资源
    最近更新 更多