简体   繁体   English

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

[英]Using QString as the key in std::unordered_map

I'm trying to use QString as the key in a std::unordered_map , however I get the error:我正在尝试使用QString作为std::unordered_map的键,但是我收到错误消息:

error C2280: 'std::hash<_Kty>::hash(const std::hash<_Kty> &)': attempting to reference a deleted function错误 C2280:“std::hash<_Kty>::hash(const std::hash<_Kty> &)”:试图引用已删除的函数

I can't switch to QHash because the value-type of the map is non-copyable.我无法切换到QHash因为地图的值类型是不可复制的。 Is there any way to make this work?有什么办法可以使这项工作?

Put the hash implementation in a header, and make sure that you include that header everywhere the map is used.hash实现放在标题中,并确保在使用地图的任何地方都包含该标题。

A trivial implementation that forwards to qHash should be sufficient:转发到qHash简单实现应该就足够了:

#include <QHash>
#include <QString>
#include <functional>

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

Even though std::size_t is larger than unsigned int on common 64 bit platforms, and thus the hash doesn't change across its full length - this isn't a problem.尽管std::size_t在常见的 64 位平台上比unsigned int大,因此散列不会在其全长范围内改变 - 这不是问题。 The standard places no such requirement on an std::hash implementation.该标准对std::hash实现没有这样的要求。

The problem is that there is no std::hash<QString>() specialization.问题是没有std::hash<QString>() It's easy enough to define your own with reasonably good performance based on the dbj2 algorithm:基于dbj2算法定义你自己的具有相当好的性能是很容易的:

#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;
        }
    };
}

include that in files which use a QString in a std::unordered_map and the error goes away.std::unordered_map使用QString文件中包含它,错误就会消失。

It seems that in newer versions of Qt, std::hash is defined for QString so you can use it with std::unordered_map directly.似乎在较新版本的 Qt 中,为 QString 定义了 std::hash,因此您可以直接将其与 std::unordered_map 一起使用。 (It works with Qt 5.14 on my machine.) (它适用于我机器上的 Qt 5.14。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM