使用QString作为std :: unordered_map中的键

时间:2018-01-30 16:24:39

标签: c++ qt c++17 stdhash

我正在尝试使用ga('myTracker.set', { 'anonymizeIp': true, 'referrer': null, 'hostname': null, 'location': null, 'page': docPage, 'geoid': null }); 作为QString中的密钥,但是我收到错误:

  

错误C2280:'std :: hash< _Kty> :: hash(const std :: hash< _Kty>&)':尝试引用已删除的函数

我无法切换到std::unordered_map,因为地图的值类型是不可复制的。有没有办法让这项工作?

3 个答案:

答案 0 :(得分:9)

hash实现放在标题中,并确保在使用地图的任何地方都包含该标题。

转发到qHash的简单实现应该足够了:

#include <QString>
#include <functional>

namespace std {
  template<> struct hash<QString> {
    std::size_t operator()(const QString& s) const {
      return qHash(s);
    }
  };
}

即使std::size_t在常见的64位平台上大于unsigned int,因此哈希不会在其全长上发生变化 - 这不是问题。该标准对std::hash实施没有这样的要求。

答案 1 :(得分:6)

问题是没有QHash专业化。根据{{​​3}}算法:

,可以很容易地定义自己的性能
std::hash<QString>()

#include <QString> #include <unordered_map> namespace std { template<> struct hash<QString> { std::size_t operator()(const QString& s) const noexcept { const QChar* str = s.data(); std::size_t hash = 5381; for (int i = 0; i < s.size(); ++i) hash = ((hash << 5) + hash) + ((str->row() << 8) | (str++)->cell()); return hash; } }; } 中使用QString的文件中包含该内容,错误就会消失。

答案 2 :(得分:0)

似乎在较新版本的 Qt 中,为 QString 定义了 std::hash,因此您可以直接将其与 std::unordered_map 一起使用。 (它适用于我机器上的 Qt 5.14。)