首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Qt QMultiHash 使用自訂結構體作 Key 需實作 qHash 與 operator==

     編輯:程式設計綜合問答

錯誤訊息

error C2665: "qHash": 17 個重載中沒有一個可以轉換所有參數類型

嘗試 QMultiHash 時,編譯器找不到適用的 qHash(const Akey&)。

解決條件

自訂型別作為 Qt 容器 (QHash/QMultiHash/QSet) 的 Key,必須提供:

  1. bool operator==(const T&, const T&) (或成員函式)
  2. 全域 uint qHash(const T&, uint seed = 0) 函式

完整範例

// 結構體定義
struct Akey {
    int a;
    char b;
    double c;

    bool operator==(const Akey& other) const {
        return a == other.a && b == other.b && c == other.c;
    }
};

struct At {
    int a;
};

// 必須在全域命名空間提供 qHash 重載
uint qHash(const Akey& key, uint seed = 0) noexcept {
    // 結合各欄位雜湊,Qt 提供 qHash 多載可直接用
    uint h = qHash(key.a, seed);
    h = qHash(key.b, h);
    h = qHash(key.c, h);
    return h;
    // 或簡單異或 (視分布需求)
    // return qHash(key.a) ^ qHash(key.b) ^ qHash(key.c);
}

// 使用
QMultiHash multiHash;
Akey k1{1, 'x', 3.14};
At v1{100};
multiHash.insert(k1, v1);

關鍵點

  • qHash **必須為全域函式**,不可放在命名空間/類別內 (除非用 ADL 技巧)。
  • 參數建議加 uint seed = 0 相容 Qt 6 新簽名。
  • 回傳 uint (32 位元無號整數)。
  • noexcept 標記可提升效能。
  • 結構體含浮點數 (double) 作 Key 時,需注意精度比較問題,建議轉整數或定義容差比較。

Qt 6 變更

Qt 6 qHash 簽名改為 size_t qHash(const T&, size_t seed = 0),為相容雙版本可寫雙重載或用模板:

template 
size_t qHash(const T& key, size_t seed = 0) noexcept {
    return qHash(key.a, seed) ^ qHash(key.b, seed) ^ qHash(key.c, seed);
}

替代方案:std::unordered_map

若專案不強制用 Qt 容器,std::unordered_map 只需定義 Hash 函式物件,無全域函式限制,跨平台更標準。

實作 operator== + 全域 qHash 即可讓自訂結構體在 QMultiHash 正常運作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved