如何使用 ICU 中的非 stl 类型(如 UnicodeString)创建unordered_map



我希望能够做到这一点:

std::unordered_map<icu::UnicodeString, icu::UnicodeString> mymap;

但是,当我这样做(并且我开始使用它)时,我收到"无法将size_t转换为UnicodeString"错误。所以我环顾四周,阅读了无序容器。这篇博文指出,我需要提供std::hash<icu::UnicodeString>的专业化,所以我确实这样做了:

namespace std
{
    template<>
    class hash<icu::UnicodeString> {
    public:
        size_t operator()(const icu::UnicodeString &s) const 
        {
            return (size_t) s.hashCode();
        }
    };
};

然而,它并不完美,但它满足了要求。但是,现在我收到以下错误:

error C2039: 'difference_type' : is not a member of 'icu_48::UnicodeString'

博客文章本身暗示我需要做更多的事情;但是,它并没有告诉我应该做什么,最后是这些评论:

除了需要哈希函数外,无序容器还需要能够测试两个键的相等性。他们执行此操作的规范方法是使用在全局命名空间中定义的 operator==() 版本。这通常是您在创建新类时习惯于构造的函数,但如果您忽略它,您将遇到本文前面看到的大量难以理解的编译器错误。

我不必在本文中处理它,因为标准库已经为 std::p air 定义了这个运算符。当然,在使用 std::p air 时,您还必须确保 T1 和 T2 有一个相等运算符。

所以,现在我有点困惑,因为operator==是为UnicodeString定义的。

因此,使用C++11,MSVC和GCC。也使用 Qt 依赖项进行编译。然后,我的问题是,为了将icu::UnicodeString类型添加到无序列图中,我还需要做什么?

根据要求,我稍后将尝试遍历地图。映射本身是一个类的一部分,称为this->mymap

std::unordered_map<icu::UnicodeString, icu::UnicodeString>::const_iterator it;
for ( it = this->mymap.begin(); it != this->mymap.end(); ++it )
{
    // access it->first, it->second etc...
}

正如 OP 发现的那样,

有人留下了一个不错的mymap->insert(key, value)这是错误的

错误错误

由于无序映射具有 2 参数插入方法,

template <class P>
iterator insert(const_iterator hint, P&& obj);

编译器将尝试将key作为const_iterator匹配,这可能就是请求difference_type类型成员的原因(它是迭代器的成员)。

插入

条目的正确方法是插入一对,

mymap.insert(std::make_pair(key, value));

或者只是使用"放置"方法,

mymap.emplace(key, value);

最新更新