簡體   English   中英

使用 QString 作為 std::unordered_map 中的鍵

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

我正在嘗試使用QString作為std::unordered_map的鍵,但是我收到錯誤消息:

錯誤 C2280:“std::hash<_Kty>::hash(const std::hash<_Kty> &)”:試圖引用已刪除的函數

我無法切換到QHash因為地圖的值類型是不可復制的。 有什么辦法可以使這項工作?

hash實現放在標題中,並確保在使用地圖的任何地方都包含該標題。

轉發到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);
    }
  };
}

盡管std::size_t在常見的 64 位平台上比unsigned int大,因此散列不會在其全長范圍內改變 - 這不是問題。 該標准對std::hash實現沒有這樣的要求。

問題是沒有std::hash<QString>() 基於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;
        }
    };
}

std::unordered_map使用QString文件中包含它,錯誤就會消失。

似乎在較新版本的 Qt 中,為 QString 定義了 std::hash,因此您可以直接將其與 std::unordered_map 一起使用。 (它適用於我機器上的 Qt 5.14。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM