本页内容

QHash Class

template <typename Key, typename T> class QHash

QHash 类是一个模板类,提供了一个基于哈希表的字典。更多内容...

头文件: #include <QHash>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core

注意:该类中的所有函数均为可重入的。

QHash 比较

类别可比较类型
相等性QHash

公共类型

公共函数

QHash()
QHash(std::initializer_list<std::pair<Key, T>> list)
QHash(InputIterator begin, InputIterator end)
QHash(const QHash<Key, T> &other)
QHash(QHash<Key, T> &&other)
~QHash()
(since 6.4) auto asKeyValueRange() &&
(since 6.4) auto asKeyValueRange() &
(since 6.4) auto asKeyValueRange() const &&
(since 6.4) auto asKeyValueRange() const &
QHash<Key, T>::iterator begin()
QHash<Key, T>::const_iterator begin() const
qsizetype capacity() const
QHash<Key, T>::const_iterator cbegin() const
QHash<Key, T>::const_iterator cend() const
void clear()
QHash<Key, T>::const_iterator constBegin() const
QHash<Key, T>::const_iterator constEnd() const
QHash<Key, T>::const_iterator constFind(const Key &key) const
QHash<Key, T>::const_key_value_iterator constKeyValueBegin() const
QHash<Key, T>::const_key_value_iterator constKeyValueEnd() const
bool contains(const Key &key) const
qsizetype count(const Key &key) const
qsizetype count() const
QHash<Key, T>::iterator emplace(Key &&key, Args &&... args)
QHash<Key, T>::iterator emplace(const Key &key, Args &&... args)
bool empty() const
QHash<Key, T>::iterator end()
QHash<Key, T>::const_iterator end() const
QHash<Key, T>::iterator erase(QHash<Key, T>::const_iterator pos)
QHash<Key, T>::iterator find(const Key &key)
QHash<Key, T>::const_iterator find(const Key &key) const
void insert(const QHash<Key, T> &other)
QHash<Key, T>::iterator insert(const Key &key, const T &value)
(since 6.11) QHash<Key, T>::iterator insert(Key &&key, T &&value)
(since 6.11) QHash<Key, T>::iterator insert(Key &&key, const T &value)
(since 6.11) QHash<Key, T>::iterator insert(const Key &key, T &&value)
(since 6.9) QHash<Key, T>::TryEmplaceResult insertOrAssign(K &&key, Value &&value)
(since 6.9) QHash<Key, T>::TryEmplaceResult insertOrAssign(Key &&key, Value &&value)
(since 6.9) QHash<Key, T>::TryEmplaceResult insertOrAssign(const Key &key, Value &&value)
(since 6.9) std::pair<QHash<Key, T>::key_value_iterator, bool> insert_or_assign(K &&key, Value &&value)
(since 6.9) std::pair<QHash<Key, T>::key_value_iterator, bool> insert_or_assign(Key &&key, Value &&value)
(since 6.9) std::pair<QHash<Key, T>::key_value_iterator, bool> insert_or_assign(const Key &key, Value &&value)
(since 6.9) QHash<Key, T>::key_value_iterator insert_or_assign(QHash<Key, T>::const_iterator hint, K &&key, Value &&value)
(since 6.9) QHash<Key, T>::key_value_iterator insert_or_assign(QHash<Key, T>::const_iterator hint, Key &&key, Value &&value)
(since 6.9) QHash<Key, T>::key_value_iterator insert_or_assign(QHash<Key, T>::const_iterator hint, const Key &key, Value &&value)
bool isEmpty() const
Key key(const T &value) const
Key key(const T &value, const Key &defaultKey) const
QHash<Key, T>::key_iterator keyBegin() const
QHash<Key, T>::key_iterator keyEnd() const
QHash<Key, T>::key_value_iterator keyValueBegin()
QHash<Key, T>::const_key_value_iterator keyValueBegin() const
QHash<Key, T>::key_value_iterator keyValueEnd()
QHash<Key, T>::const_key_value_iterator keyValueEnd() const
QList<Key> keys() const
QList<Key> keys(const T &value) const
float load_factor() const
bool remove(const Key &key)
(since 6.1) qsizetype removeIf(Predicate pred)
void reserve(qsizetype size)
qsizetype size() const
void squeeze()
void swap(QHash<Key, T> &other)
T take(const Key &key)
(since 6.9) QHash<Key, T>::TryEmplaceResult tryEmplace(K &&key, Args &&... args)
(since 6.9) QHash<Key, T>::TryEmplaceResult tryEmplace(Key &&key, Args &&... args)
(since 6.9) QHash<Key, T>::TryEmplaceResult tryEmplace(const Key &key, Args &&... args)
(since 6.9) QHash<Key, T>::TryEmplaceResult tryInsert(K &&key, const T &value)
(since 6.9) QHash<Key, T>::TryEmplaceResult tryInsert(const Key &key, const T &value)
(since 6.9) std::pair<QHash<Key, T>::key_value_iterator, bool> try_emplace(K &&key, Args &&... args)
(since 6.9) std::pair<QHash<Key, T>::key_value_iterator, bool> try_emplace(Key &&key, Args &&... args)
(since 6.9) std::pair<QHash<Key, T>::key_value_iterator, bool> try_emplace(const Key &key, Args &&... args)
(since 6.9) QHash<Key, T>::key_value_iterator try_emplace(QHash<Key, T>::const_iterator hint, K &&key, Args &&... args)
(since 6.9) QHash<Key, T>::key_value_iterator try_emplace(QHash<Key, T>::const_iterator hint, Key &&key, Args &&... args)
(since 6.9) QHash<Key, T>::key_value_iterator try_emplace(QHash<Key, T>::const_iterator hint, const Key &key, Args &&... args)
T value(const Key &key) const
T value(const Key &key, const T &defaultValue) const
QList<T> values() const
QHash<Key, T> &operator=(QHash<Key, T> &&other)
QHash<Key, T> &operator=(const QHash<Key, T> &other)
T &operator[](const Key &key)
const T operator[](const Key &key) const
(since 6.1) qsizetype erase_if(QHash<Key, T>&hash, Predicatepred)
(since 6.5) size_t qHash(Enumkey, size_tseed= 0)
size_t qHash(const QStringRef&key, size_tseed= 0)
size_t qHash(const QMqttTopicFilter&filter, size_tseed= 0)
size_t qHash(const QSslKeyingMaterial&key)
size_t qHash(const QGeoCoordinate&coordinate, size_tseed= 0)
(since 6.0) size_t qHash(QByteArrayViewkey, size_tseed= 0)
size_t qHash(const QMqttTopicName&name, size_tseed= 0)
size_t qHash(QSslEllipticCurvekey, size_tseed= 0)
size_t qHash(ucharkey, size_tseed= 0)
size_t qHash(uint密钥, size_t种子= 0)
size_t qHash(ulongkey, size_tseed= 0)
size_t qHash(ushortkey, size_tseed= 0)
(since 6.0) size_t qHash(wchar_tkey, size_tseed= 0)
size_t qHash(QDatekey, size_tseed= 0)
size_t qHash(const QOcspResponse&key, size_tseed= 0)
size_t qHash(QLatin1StringViewkey, size_tseed= 0)
size_t qHash(const QSslCertificate&key, size_tseed= 0)
(since 6.0) size_t qHash(QPointkey, size_tseed= 0)
size_t qHash(const QSslError&key, size_tseed= 0)
size_t qHash(QTimekey, size_tseed= 0)
size_t qHash(const QSslKeyingMaterial&key, size_tseed)
(since 6.9) size_t qHash(Tkey, size_tseed)
size_t qHash(charkey, size_tseed= 0)
(since 6.0) size_t qHash(char16_t密钥, size_t初始值= 0)
(since 6.0) size_t qHash(char32_tkey, size_tseed= 0)
(since 6.0) size_t qHash(char8_t密钥, size_t初始值= 0)
size_t qHash(const QBitArray&key, size_tseed= 0)
size_t qHash(const QByteArray&key, size_tseed= 0)
size_t qHash(const QCharkey, size_tseed= 0)
size_t qHash(const QDateTime&key, size_tseed= 0)
size_t qHash(const QHash<Key, T>&key, size_tseed= 0)
size_t qHash(const QSet<T>&key, size_tseed= 0)
size_t qHash(const QString&key, size_tseed= 0)
(since 6.0) size_t qHash(const QTypeRevision&key, size_tseed= 0)
size_t qHash(const QUrl&key, size_tseed= 0)
size_t qHash(const QVersionNumber&key, size_tseed= 0)
size_t qHash(const T*key, size_tseed= 0)
(since 6.12) size_t qHash(const std::optional<T>&key, size_tseed= 0)
size_t qHash(const std::pair<T1, T2>&key, size_tseed= 0)
size_t qHash(doublekey, size_tseed= 0)
size_t qHash(float密钥, size_t初始值= 0)
size_t qHash(intkey, size_tseed= 0)
size_t qHash(longkey, size_tseed= 0)
size_t qHash(long doublekey, size_tseed= 0)
(since 6.8) size_t qHash(qint128key, size_tseed= 0)
size_t qHash(qint64key, size_tseed= 0)
(since 6.8) size_t qHash(quint128key, size_tseed= 0)
size_t qHash(quint64key, size_tseed= 0)
size_t qHash(shortkey, size_tseed= 0)
size_t qHash(signed charkey, size_tseed= 0)
(since 6.0) size_t qHash(std::nullptr_tkey, size_tseed= 0)
size_t qHashBits(const void*p, size_tlen, size_tseed= 0)
(since 6.0) size_t qHashMulti(size_tseed, const T &...args)
(since 6.0) size_t qHashMultiCommutative(size_t种子, const T &...参数)
size_t qHashRange(InputIteratorfirst, InputIteratorlast, size_tseed= 0)
size_t qHashRangeCommutative(InputIteratorfirst, InputIteratorlast, size_tseed= 0)
bool operator!=(const QHash<Key, T>&lhs, const QHash<Key, T>&rhs)
QDataStream &operator<<(QDataStream&out, const QHash<Key, T>&hash)
bool operator==(const QHash<Key, T>&lhs, const QHash<Key, T>&rhs)
QDataStream &operator>>(QDataStream&in, QHash<Key, T>&hash)

宏

详细说明

QHash<KEY, T> 是 Qt 的泛型容器类之一,其中Key 表示用于查找的键类型,T 表示映射值的类型。它存储 (键, 值) 对,并能非常快速地查找与某个键关联的值。

QHash 提供的功能与QMap 非常相似。区别在于:

  • QHash 的查找速度比QMap 更快。(详情请参阅“算法复杂度”。)
  • 遍历QMap 时,项目总是按键值排序。而 QHash 中的项目顺序则不固定。
  • QMap 的键类型必须提供 operator<()。QHash 的键类型必须提供 operator==() 以及一个名为qHash() 的全局哈希函数(参见qHash )。

以下是一个使用QString 作为键、int 作为值的 QHash 示例:

QHash<QString, int> hash;

要将 (键, 值) 对插入哈希表中,可以使用 operator[]():

hash["one"] = 1;
hash["three"] = 3;
hash["seven"] = 7;

这将以下三个 (键, 值) 对插入到 QHash 中:("one", 1)、("three", 3) 和 ("seven", 7)。向哈希表中插入项的另一种方法是使用insert():

hash.insert("twelve", 12);

要查询一个值,可以使用 operator[]() 或value():

int num1 = hash["thirteen"];
int num2 = hash.value("thirteen");

如果哈希中没有指定键的项,这些函数将返回一个通过默认构造初始化的值。

若要检查哈希中是否包含某个特定键,请使用contains():

int timeout = 30;
if (hash.contains("TIMEOUT"))
    timeout = hash.value("TIMEOUT");

此外,value() 还有一个重载版本,当哈希表中不存在指定键的条目时,该版本会将第二个参数用作默认值:

int timeout = hash.value("TIMEOUT", 30);

通常,我们建议您在哈希中查找键时,使用contains() 和value(),而不是 operator[]()。原因是,如果不存在具有相同键的项,operator[]() 会默默地将该项插入到哈希中(除非该哈希是 const 类型)。 例如,以下代码片段将在内存中创建 1000 个项:

// WRONG
QHash<int, QWidget *> hash;
//...
for (int i = 0; i < 1000; ++i) {
    if (hash[i] == okButton)
        cout << "Found button at index " << i << endl;
}

为避免此问题,请将上文中的hash[i] 替换为hash.value(i) 。

在内部,QHash 使用哈希表进行查找。该哈希表会自动扩展,以提供快速的查找速度,同时避免浪费过多内存。如果您已经大致知道 QHash 将包含多少个项目,仍可通过调用 `reserve()` 来控制哈希表的大小,但这并非获得良好性能的必要条件。 您还可以调用capacity() 来获取哈希表的大小。

如果从表中删除项,QHash 不会自动缩小。若要最大限度地减少哈希表占用的内存,请调用squeeze()。

要遍历 QHash 中存储的所有 (键, 值) 对,请使用asKeyValueRange():

for (const auto &[key, value] : std::as_const(hash).asKeyValueRange())
    cout << qPrintable(key) << ": " << value << endl;

该函数返回一个范围对象,可用于结构化绑定。若需手动控制迭代器,也可使用传统的STL 风格迭代器(QHash::const_iterator 和QHash::iterator ):

for (auto it = hash.cbegin(); it != hash.cend(); ++it)
    cout << qPrintable(it.key()) << ": " << it.value() << endl;

要修改值,请使用迭代器:

for (auto it = hash.begin(); it != hash.end(); ++it)
    it.value() += 1;

QHash 还提供了Java 风格的迭代器(QHashIterator 和QMutableHashIterator ),以确保兼容性。

QHash 是不带顺序的,因此不能假设迭代器的序列是可预测的。如果需要按键值排序,请使用QMap 。

QHash 允许每个键仅有一个值。如果使用已在 QHash 中存在的键调用insert(),则之前的值将被清除。例如:

hash.insert("plenty", 100);
hash.insert("plenty", 2000);
// hash.value("plenty") == 2000

若需在哈希表中为同一键存储多个条目,请使用 `QMultiHash`。

若仅需从哈希表中提取值(而非键),也可使用基于范围的 for 循环:

QHash<QString, int> hash;
//...
for (int value : std::as_const(hash))
    cout << value << endl;

可以通过多种方式从哈希表中删除项目。一种方法是调用 `remove()`;这将删除所有具有指定键的项目。另一种方法是使用 `QMutableHashIterator::remove()`。此外,还可以使用 `clear()` 清空整个哈希表。

QHash 的键和值必须是可赋值的数据类型。例如,你不能将QWidget 作为值存储;相反,应存储QWidget *。

哈希函数

QHash 的键类型除了必须是可赋值的数据类型外,还有其他要求:它必须提供 operator==() 运算符,并且还必须有一个哈希函数,该函数能针对键类型的参数返回一个哈希值。

哈希函数根据键计算一个数值。它可以采用任何可想象的算法,只要给定相同的参数时,它总能返回相同的值即可。 换言之,如果e1 == e2 ,那么hash(e1) == hash(e2) 也必须成立。不过,为了获得良好的性能,哈希函数应尽可能地针对不同的键返回不同的哈希值。

针对键类型K 的哈希函数可通过两种不同方式提供。

第一种方式是在K 的命名空间中重载qHash() 。qHash() 函数必须具有以下其中一种签名:

size_tqHash(K key,size_t seed);
size_t qHash(const K &key, size_t seed);

size_t qHash(K key);        // deprecated, do not use
size_t qHash(const K &key); // deprecated, do not use

两个参数的重载版本接受一个无符号整数,该整数应用于哈希函数计算的初始化。该初始化值由 QHash 提供,旨在防止出现一类algorithmic complexity attacks 。

注意:在 Qt 6中 ,可以定义仅接受一个参数的qHash() 重载;但此功能已被标记为弃用。从 Qt 7 开始,必须使用双参数重载。 如果为某个键类型同时定义了单参数和双参数重载,QHash 将使用后者(请注意,您可以直接定义双参数版本,并为种子参数设置默认值)。 在 Qt 6 中,可以通过定义宏 `QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD ` 来禁用对单参数qHash 重载的支持。

提供哈希函数的第二种方法是针对键类型K 特化std::hash 类,并为其提供一个合适的函数调用运算符:

namespace std
{
    template <> struct hash<K>
    {
        // seed is optional
        size_t operator()(const K &key, size_t seed = 0) const;
    };
}

种子参数的含义与qHash() 相同,可以省略。

第二种方法允许在 QHash 和 C++ 标准库中的无序关联容器之间复用相同的哈希函数。如果为某种类型同时提供了qHash() 的重载和std::hash 的特化,则优先使用qHash() 的重载。

以下是可作为 QHash 键的 C++ 和 Qt 类型的部分列表:任何整数类型(char、unsigned long 等)、任何指针类型、QChar 、QString 以及QByteArray 。对于所有这些类型,<QHash> 头文件都定义了qHash() 函数,用于计算合适的哈希值。 许多其他 Qt 类也为其类型声明了qHash 的重载;请参阅各类的文档。

若要使用其他类型作为键,请确保提供 operator==() 以及哈希实现。

可以使用便捷函数qHashMulti() 来为自定义类型实现qHash(),通常情况下,用户希望根据多个字段生成哈希值:

示例:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

class Employee
{
public:
    Employee() {}
    Employee(const QString &name, QDate dateOfBirth);
    QString name() const { return myName; }
    QDate dateOfBirth() const { return myDateOfBirth; }
    //...

private:
    QString myName;
    QDate myDateOfBirth;
};

inline bool operator==(const Employee &e1, const Employee &e2)
{
    return e1.name() == e2.name()
           && e1.dateOfBirth() == e2.dateOfBirth();
}

inline size_t qHash(const Employee &key, size_t seed)
{
    return qHashMulti(seed, key.name(), key.dateOfBirth());
}

#endif // EMPLOYEE_H

在上例中,我们依赖于 Qt 自身对 `qHash()` 的实现,通过 `QString ` 和 `QDate ` 分别获取员工姓名和出生日期对应的哈希值。

请注意,Qt 提供的qHash() 重载实现可能会随时发生变化。切勿依赖qHash() 在不同 Qt 版本中(对于相同的输入)会返回相同结果这一事实。

算法复杂度攻击

所有哈希表都容易受到一类特定的拒绝服务攻击,在此类攻击中,攻击者会精心预先计算出一组不同的键,这些键在哈希表中会被哈希到同一个桶中(甚至具有完全相同的哈希值)。 该攻击旨在当数据输入到表中时,引发最坏情况下的算法行为(即 O(n) 而不是摊销时间复杂度 O(1),详情请参阅“算法复杂度”)。

为了避免这种最坏情况下的行为,可以通过向 `qHash()` 函数计算哈希值时添加随机种子(salt)来抵消攻击的影响。 该种子由 QHash 在每个进程中自动生成一次,然后由 QHash 作为qHash() 函数的双参数重载版本的第二个参数传递。

QHash 的这种随机化功能默认处于启用状态。尽管程序绝不应依赖特定的 QHash 排序,但在某些情况下(例如调试或回归测试时),您可能需要临时获得确定性行为。要禁用随机化,请将环境变量QT_HASH_SEED 设置为 0。或者,您也可以调用QHashSeed::setDeterministicGlobalSeed() 函数。

另请参阅 QHashIterator 、QMutableHashIterator 、QMap 以及QSet 。

成员类型文档

QHash::ConstIterator

QHash::const_iterator 的 Qt 风格同义词。

QHash::Iterator

QHash::iterator 的 Qt 风格同义词。

QHash::const_key_value_iterator

typedef QHash::const_key_value_iterator 为QHash 提供了一个STL风格的const迭代器。

QHash::const_key_value_iterator 与QHash::const_iterator 本质上相同,区别在于其 operator*() 返回键/值对,而不是仅返回一个值。

另请参阅 QKeyValueIterator 。

[alias] QHash::difference_type

ptrdiff_t 的 typedef。为兼容 STL 而提供。

[alias] QHash::key_type

Key 的 typedef。为兼容 STL 而提供。

QHash::key_value_iterator

QHash::key_value_iterator 类型定义为QHash 提供了一个 STL 风格的迭代器。

QHash::key_value_iterator 与QHash::iterator 本质上相同,区别在于其 operator*() 返回键值对而非单个值。

另请参阅 QKeyValueIterator 。

[alias] QHash::mapped_type

T 的 typedef。为兼容 STL 而提供。

[alias] QHash::size_type

int 的 typedef。为兼容 STL 而提供。

成员函数文档

[noexcept default] QHash::QHash()

创建一个空哈希表。

另请参阅 clear()。

QHash::QHash(std::initializer_list<std::pair<Key, T>> list)

根据初始化列表list 中的每个元素的副本,构建一个哈希表。

template <typename InputIterator> QHash::QHash(InputIterator begin, InputIterator end)

构建一个哈希表,其中包含迭代器范围 [begin,end) 中每个元素的副本。该范围迭代的元素必须是具有first 和second 数据成员(如std::pair )的对象,且分别可转换为Key 和T ;或者,迭代器必须具有key() 和value() 成员函数,分别返回可转换为Key 的键和可转换为T 的值。

[noexcept] QHash::QHash(const QHash<Key, T> &other)

创建other 的副本。

由于 QHash默认是共享的,因此该操作的时间复杂度为常数。这使得从函数中返回 QHash 非常快。如果共享的实例被修改,则会进行复制(写时复制),此过程的时间复杂度为线性。

另请参阅 operator=()。

[noexcept] QHash::QHash(QHash<Key, T> &&other)

通过“move”操作构造一个 QHash 实例,使其指向与other 所指向的同一对象。

QHash::~QHash()

销毁哈希表。对哈希表中值的引用以及该哈希表的所有迭代器将失效。

[since 6.4] auto QHash::asKeyValueRange() &&

[since 6.4] auto QHash::asKeyValueRange() &

[since 6.4] auto QHash::asKeyValueRange() const &&

[since 6.4] auto QHash::asKeyValueRange() const &

返回一个范围对象,允许以键值对的形式遍历该哈希表。例如,该范围对象可与结构化绑定声明结合,用于基于范围的 for 循环中:

QHash<QString, int> hash;
hash.insert("January", 1);
hash.insert("February", 2);
// ...
hash.insert("December", 12);

for (auto [key, value] : hash.asKeyValueRange()) {
    cout << qPrintable(key) << ": " << value << endl;
    --value; // convert to JS month indexing
}

请注意,通过此方式获得的键和值都是对哈希中相应项的引用。具体来说,修改该值将直接修改哈希本身。

警告: 当下次对哈希调用非 const 函数,或者当哈希被销毁时,返回的 迭代器/引用应被视为失效。

这些函数在 Qt 6.4 中引入。

另请参阅 QKeyValueIterator 。

QHash<Key, T>::iterator QHash::begin()

返回一个指向哈希表中第一个项的STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用将被视为失效。

另请参阅 constBegin() 和end()。

[noexcept] QHash<Key, T>::const_iterator QHash::begin() const

警告: 下次在哈希上调用非 const 函数时,或者当哈希被销毁时,返回的 迭代器/引用应被视为已失效。

这是一个重载函数。

[noexcept] qsizetype QHash::capacity() const

返回QHash 内部哈希表中的桶数。

此函数的唯一目的是提供一种精细调整QHash 内存使用情况的手段。通常情况下,您几乎不需要调用此函数。如果您想知道哈希表中包含多少个项,请调用size()。

另请参阅 reserve() 和squeeze()。

[noexcept] QHash<Key, T>::const_iterator QHash::cbegin() const

返回一个指向哈希表中第一个元素的常量STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或哈希表被销毁时,所返回的 迭代器/引用将被视为失效。

另请参阅 begin() 和cend()。

[noexcept] QHash<Key, T>::const_iterator QHash::cend() const

返回一个指向哈希表中最后一个元素之后那个“虚构”元素的 constSTL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数时,或在哈希表被销毁时,返回的 迭代器/引用应被视为无效。

另请参阅 cbegin() 和end()。

[noexcept(...)] void QHash::clear()

从哈希表中移除所有项,并释放其占用的所有内存。

注意: 当std::is_nothrow_destructible<Node>::value 的值是true 时,此 函数为noexcept。

另请参阅 remove()。

[noexcept] QHash<Key, T>::const_iterator QHash::constBegin() const

返回一个指向哈希表中第一个元素的常量STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 begin() 和constEnd()。

[noexcept] QHash<Key, T>::const_iterator QHash::constEnd() const

返回一个指向哈希表中最后一个项之后的虚拟项的常量STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数时,或者当哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 constBegin() 和end()。

[noexcept] QHash<Key, T>::const_iterator QHash::constFind(const Key &key) const

返回一个迭代器,该迭代器指向哈希表中具有key 的项。

如果哈希中不存在具有key 的项,则该函数返回constEnd()。

警告: 当下次对哈希调用非 const 函数时,或者当哈希被销毁时,返回的 迭代器/引用应被视为失效。

另请参阅 find()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::constKeyValueBegin() const

返回一个指向哈希表中第一个条目的常量STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 keyValueBegin()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::constKeyValueEnd() const

返回一个指向哈希表中最后一个条目之后那个虚构条目的、STL 风格的const迭代器。

警告: 当下次对哈希表调用非 const 函数,或哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 constKeyValueBegin()。

[noexcept] bool QHash::contains(const Key &key) const

如果哈希中包含一个具有key 的项,则返回true ;否则返回false 。

另请参阅 count()。

[noexcept] qsizetype QHash::count(const Key &key) const

返回与key 关联的项目数量。

另请参阅 contains()。

[noexcept] qsizetype QHash::count() const

与size()相同。

这是一个重载函数。

template <typename... Args> QHash<Key, T>::iterator QHash::emplace(Key &&key, Args &&... args)

template <typename... Args> QHash<Key, T>::iterator QHash::emplace(const Key &key, Args &&... args)

将一个新元素插入到容器中。该新元素会就地构建,并使用args 作为其构建的参数。如果该元素已在容器中存在,则会被替换。

返回一个指向新元素的迭代器。

警告:返回的 迭代器/引用在下次对哈希调用非 const 函数时,或当哈希被销毁时,应被视为已失效。

[noexcept] bool QHash::empty() const

提供此函数是为了兼容 STL。它等同于 `isEmpty()`,如果哈希表为空,则返回 `true`;否则返回 `false`。

[noexcept] QHash<Key, T>::iterator QHash::end()

返回一个STL 风格的迭代器,该迭代器指向哈希表中最后一个元素之后的虚拟元素。

警告: 当下次对哈希表调用非 const 函数,或哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 begin() 和constEnd()。

[noexcept] QHash<Key, T>::const_iterator QHash::end() const

警告: 当您下次对哈希调用非 const 函数时,或者当哈希被销毁时,应将返回的 迭代器/引用视为已失效。

这是一个重载函数。

QHash<Key, T>::iterator QHash::erase(QHash<Key, T>::const_iterator pos)

从哈希中移除与迭代器pos 关联的(键, 值)对,并返回指向哈希中下一个项的迭代器。

此函数绝不会导致QHash 对其内部数据结构进行重新哈希。这意味着在迭代过程中可以安全地调用该函数,且不会影响哈希中项的顺序。例如:

QHash<QObject *, int> objectHash;
//...
QHash<QObject *, int>::iterator i = objectHash.find(obj);
while (i != objectHash.end() && i.key() == obj) {
    if (i.value() == 0) {
        i = objectHash.erase(i);
    } else {
        ++i;
    }
}

警告: 当下次对哈希调用非 const 函数,或哈希被销毁时,返回的 迭代器/引用应被视为失效。

另请参阅 remove()、take() 和find()。

QHash<Key, T>::iterator QHash::find(const Key &key)

返回一个迭代器,该迭代器指向哈希表中具有key 的项。

如果哈希中不存在具有key 的项,则该函数返回end()。

如果哈希表中包含多个具有key 的项,则该函数返回一个指向最近插入的值的迭代器。通过递增该迭代器,可以访问其他值。例如,以下代码演示了如何遍历所有具有相同键的项:

QHash<QString, int> hash;
//...
QHash<QString, int>::const_iterator i = hash.find("HDR");
while (i != hash.end() && i.key() == "HDR") {
    cout << i.value() << endl;
    ++i;
}

警告: 当下次对哈希调用非 const 函数,或哈希被销毁时,返回的 迭代器/引用应被视为失效。

另请参阅 value() 和values()。

[noexcept] QHash<Key, T>::const_iterator QHash::find(const Key &key) const

警告: 当您下次对哈希调用非 const 函数时,或者当哈希被销毁时,应将返回的 迭代器/引用视为已失效。

这是一个重载函数。

void QHash::insert(const QHash<Key, T> &other)

将other 哈希中的所有项插入到此哈希中。

如果两个哈希表中存在相同的键,则该键的值将被替换为other 中存储的值。

QHash<Key, T>::iterator QHash::insert(const Key &key, const T &value)

插入一个新条目,其键为key ,值为value 。

如果已经存在键为key 的项,则该项的值将被替换为value 。

如果插入的键/值对的键与现有键相同,则会替换现有的值。

返回一个指向新元素或更新后元素的迭代器。

警告: 当您下次在哈希表上调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用应被视为失效。

[since 6.11] QHash<Key, T>::iterator QHash::insert(Key &&key, T &&value)

[since 6.11] QHash<Key, T>::iterator QHash::insert(Key &&key, const T &value)

[since 6.11] QHash<Key, T>::iterator QHash::insert(const Key &key, T &&value)

这些函数是在 Qt 6.11 中引入的。

[since 6.9] template <typename K, typename Value> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> QHash<Key, T>::TryEmplaceResult QHash::insertOrAssign(K &&key, Value &&value)

[since 6.9] template <typename Value> QHash<Key, T>::TryEmplaceResult QHash::insertOrAssign(Key &&key, Value &&value)

[since 6.9] template <typename Value> QHash<Key, T>::TryEmplaceResult QHash::insertOrAssign(const Key &key, Value &&value)

尝试使用key 和value 插入一个项。如果已经存在一个key 的项,则将其值覆盖为value 。

返回一个TryEmplaceResult 的实例,该结构体包含指向该项的iterator ,以及一个布尔值inserted ,用于表示该项是新创建的(true )还是此前已存在(false )。

这些函数在 Qt 6.9 中引入。

另请参阅 insert()、tryEmplace() 和tryInsert()。

[since 6.9] template <typename K, typename Value> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash::insert_or_assign(K &&key, Value &&value)

[since 6.9] template <typename Value> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash::insert_or_assign(Key &&key, Value &&value)

[since 6.9] template <typename Value> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash::insert_or_assign(const Key &key, Value &&value)

尝试使用key 和value 插入一个项。如果已经存在key 的项,则将其值覆盖为value 。

返回一个由指向该项的迭代器和一个布尔值组成的元组,该布尔值表示该项是新创建的(true )还是此前已存在(false )。

提供这些函数是为了与标准库保持兼容性。

这些函数是在 Qt 6.9 中引入的。

另请参阅 insert()、tryEmplace()、tryInsert() 和insertOrAssign()。

[since 6.9] template <typename K, typename Value> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> QHash<Key, T>::key_value_iterator QHash::insert_or_assign(QHash<Key, T>::const_iterator hint, K &&key, Value &&value)

[since 6.9] template <typename Value> QHash<Key, T>::key_value_iterator QHash::insert_or_assign(QHash<Key, T>::const_iterator hint, Key &&key, Value &&value)

[since 6.9] template <typename Value> QHash<Key, T>::key_value_iterator QHash::insert_or_assign(QHash<Key, T>::const_iterator hint, const Key &key, Value &&value)

尝试使用key 和value 插入一个项。如果已经存在一个具有key 的项,则其值将被value 覆盖。

返回一个由指向该项的迭代器和一个布尔值组成的元组,该布尔值表示该项是新创建的(true )还是已存在(false )。

hint 将被忽略。

提供这些函数是为了与标准库保持兼容性。

这些函数在 Qt 6.9 中引入。

另请参阅 insert()、tryEmplace() 和insertOrAssign()。

[noexcept] bool QHash::isEmpty() const

如果哈希表中不包含任何项,则返回true ;否则返回false。

另请参阅 size()。

[noexcept] Key QHash::key(const T &value) const

[noexcept] Key QHash::key(const T &value, const Key &defaultKey) const

返回映射到value 的第一个键。如果哈希中不存在映射到value 的项,则返回defaultKey ;如果未提供此参数,则返回默认构造的键。

此函数可能运行较慢(线性时间),因为QHash 的内部数据结构是为按键快速查找而优化的,而非按值查找。

[noexcept] QHash<Key, T>::key_iterator QHash::keyBegin() const

返回一个指向哈希表中第一个键的 constSTL 风格迭代器。

警告: 当下次在哈希表上调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 keyEnd()。

[noexcept] QHash<Key, T>::key_iterator QHash::keyEnd() const

返回一个指向哈希表中最后一个键之后那个虚构项的常量STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 keyBegin()。

QHash<Key, T>::key_value_iterator QHash::keyValueBegin()

返回一个指向哈希表中第一个条目的STL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 keyValueEnd()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::keyValueBegin() const

返回一个指向哈希表中第一个条目的 constSTL 风格迭代器。

警告: 当下次对哈希表调用非 const 函数,或者哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 keyValueEnd()。

QHash<Key, T>::key_value_iterator QHash::keyValueEnd()

返回一个STL 风格的迭代器,该迭代器指向哈希表中最后一个条目之后的虚拟条目。

警告: 当您下次对哈希表调用非 const 函数,或者当哈希表被销毁时,返回的 迭代器/引用应被视为已失效。

另请参阅 keyValueBegin()。

[noexcept] QHash<Key, T>::const_key_value_iterator QHash::keyValueEnd() const

返回一个指向哈希表中最后一个条目之后那个虚构条目的、STL 风格的const迭代器。

警告: 当您下次对哈希表调用非 const 函数,或哈希表被销毁时,返回的 迭代器/引用应被视为失效。

另请参阅 keyValueBegin()。

QList<Key> QHash::keys() const

返回一个包含哈希中所有键的列表,顺序不固定。

该顺序保证与values() 所使用的顺序一致。

该函数以线性时间复杂度创建一个新列表。通过将keyBegin() 转换为keyEnd() 进行迭代,可以避免由此产生的时间和内存消耗。

另请参阅 values() 和key()。

QList<Key> QHash::keys(const T &value) const

返回一个列表,其中包含与值value 关联的所有键,顺序不固定。

该函数可能运行较慢(线性时间复杂度),因为QHash 的内部数据结构是为根据键快速查找而优化的,而非根据值。

这是一个重载函数。

[noexcept] float QHash::load_factor() const

返回QHash 内部哈希表的当前负载因子。这与capacity()/size()的功能相同。所使用的实现将力求将负载因子维持在0.25到0.5之间。这样可以避免出现过多的哈希表冲突,从而防止性能下降。

即使在较低的负载因子下,哈希表的实现也具有非常低的内存开销。

此方法纯粹用于诊断目的,您通常无需自行调用它。

另请参阅 reserve() 和squeeze()。

bool QHash::remove(const Key &key)

从哈希表中移除具有键key 的项。如果该键在哈希表中存在且该项已被移除,则返回true;否则返回false。

另请参阅 clear() 和take()。

[since 6.1] template <typename Predicate> qsizetype QHash::removeIf(Predicate pred)

从哈希表中移除所有满足谓词pred 返回 true 的元素。

该函数支持接受QHash<Key, T>::iterator 类型参数或std::pair<const Key &, T &> 类型参数的谓词。

返回被移除的元素个数(如有)。

该函数在 Qt 6.1 中引入。

另请参见 clear() 和take()。

void QHash::reserve(qsizetype size)

确保QHash 的内部哈希表有足够的空间来存储至少size 个条目,而无需扩展哈希表。

这意味着哈希表将包含至少 2 *size 个桶,以确保良好的性能

此函数对于需要构建大型哈希表且希望避免重复重新分配的代码非常有用。例如:

QHash<QString, int> hash;
hash.reserve(20000);
for (int i = 0; i < 20000; ++i)
    hash.insert(keys[i], values[i]);

理想情况下,size 应为哈希表中预期的最大项目数。此时QHash 将选择尽可能少的桶数,以允许在无需扩容内部哈希表的情况下,在表中存储size 个项目。如果size 估计过低,最坏的情况只是QHash 的速度会稍慢一些。

通常情况下,您几乎无需调用此函数。QHash 的内部哈希表会自动扩展,以在不浪费过多内存的情况下提供良好的性能。

另请参阅 squeeze() 和capacity()。

[noexcept] qsizetype QHash::size() const

返回哈希表中项的数量。

另请参阅 isEmpty() 和count()。

void QHash::squeeze()

缩小QHash 的内部哈希表大小,以节省内存。

此函数的唯一目的是提供一种精细调整QHash 内存使用情况的方法。通常情况下,您几乎不需要调用此函数。

另请参阅 reserve() 和capacity()。

[noexcept] void QHash::swap(QHash<Key, T> &other)

将此哈希值与other 进行交换。此操作速度极快,且绝不会失败。

T QHash::take(const Key &key)

从哈希表中移除键为key 的项,并返回与其关联的值。

如果该项在哈希表中不存在,则该函数仅返回一个通过默认构造生成的值。

如果您不使用返回值,则使用 `remove()` 更高效。

另请参阅 remove()。

[since 6.9] template <typename K, typename... Args> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> QHash<Key, T>::TryEmplaceResult QHash::tryEmplace(K &&key, Args &&... args)

[since 6.9] template <typename... Args> QHash<Key, T>::TryEmplaceResult QHash::tryEmplace(Key &&key, Args &&... args)

[since 6.9] template <typename... Args> QHash<Key, T>::TryEmplaceResult QHash::tryEmplace(const Key &key, Args &&... args)

插入一个新项,其key 属性为该项,且值由args 构造而成。如果已存在具有key 的项,则不进行插入操作。

返回一个TryEmplaceResult 的实例,该结构包含指向新创建项(或阻止插入操作的已存在项)的iterator ,以及一个布尔值inserted ,用于指示插入操作是否成功。

例如,这可用于避免比较新旧大小或进行双重查找的模式。以前您可能写过如下代码:

QHash<int, MyType> hash;
// [...]
int myKey = getKey();
qsizetype oldSize = hash.size();
MyType &elem = hash[myKey];
if (oldSize != hash.size()) // Size changed: new element!
    initialize(elem);
// [use elem...]

现在可以改写为:

QHash<int, MyType> hash;
// [...]
int myKey = getKey();
auto result = hash.tryEmplace(myKey);
if (result.inserted) // New element!
    initialize(*result.iterator);
// [use result.iterator...]

这些函数在 Qt 6.9 中引入。

另请参阅 emplace()、tryInsert() 和insertOrAssign()。

[since 6.9] template <typename K> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> QHash<Key, T>::TryEmplaceResult QHash::tryInsert(K &&key, const T &value)

[since 6.9] QHash<Key, T>::TryEmplaceResult QHash::tryInsert(const Key &key, const T &value)

插入一个新项,其key 为,值为value 。如果已存在key 的项,则不进行插入。

返回一个TryEmplaceResult 实例,该结构体包含指向新创建项(或阻止插入操作的已存在项)的iterator ,以及一个布尔值inserted ,用于指示插入操作是否成功。

这些函数在 Qt 6.9 中引入。

另请参阅 insert()、tryEmplace() 和insertOrAssign()。

[since 6.9] template <typename K, typename... Args> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash::try_emplace(K &&key, Args &&... args)

[since 6.9] template <typename... Args> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash::try_emplace(Key &&key, Args &&... args)

[since 6.9] template <typename... Args> std::pair<QHash<Key, T>::key_value_iterator, bool> QHash::try_emplace(const Key &key, Args &&... args)

插入一个新项,其key 和值由args 构造而成。如果已经存在一个key 的项,则不进行插入操作。

返回一个元组,其中包含指向已插入项(或阻止插入的项)的迭代器,以及一个表示插入是否成功的布尔值。

提供这些函数是为了与标准库保持兼容性。

这些函数在 Qt 6.9 中引入。

另请参见 emplace()、tryEmplace()、tryInsert() 和insertOrAssign()。

[since 6.9] template <typename K, typename... Args> requires if_heterogeneously_searchable<K> && if_key_constructible_from<K> QHash<Key, T>::key_value_iterator QHash::try_emplace(QHash<Key, T>::const_iterator hint, K &&key, Args &&... args)

[since 6.9] template <typename... Args> QHash<Key, T>::key_value_iterator QHash::try_emplace(QHash<Key, T>::const_iterator hint, Key &&key, Args &&... args)

[since 6.9] template <typename... Args> QHash<Key, T>::key_value_iterator QHash::try_emplace(QHash<Key, T>::const_iterator hint, const Key &key, Args &&... args)

插入一个新项,其key 为指定值,且值由args 构造而成。如果已存在具有key 的项,则不进行插入。

返回已插入项的迭代器,或返回阻止插入操作的项。

hint 将被忽略。

提供这些函数是为了与标准库保持兼容性。

这些函数在 Qt 6.9 中引入。

另请参阅 emplace()、tryEmplace()、tryInsert() 和insertOrAssign()。

[noexcept] T QHash::value(const Key &key) const

[noexcept] T QHash::value(const Key &key, const T &defaultValue) const

返回与key 关联的值。

如果哈希表中不存在名为key 的项,则该函数返回defaultValue ;若未提供此参数,则返回默认构造的值。

QList<T> QHash::values() const

返回一个列表,其中包含哈希表中的所有值,顺序不固定。

该顺序保证与keys() 所使用的顺序一致。

该函数以线性时间复杂度创建一个新列表。通过从 `keyValueBegin()` 迭代到 `keyValueEnd()`,可以避免由此产生的时间和内存开销。

另请参阅 keys() 和value()。

[noexcept] QHash<Key, T> &QHash::operator=(QHash<Key, T> &&other)

将other 通过Move操作赋值给此QHash 实例。

[noexcept] QHash<Key, T> &QHash::operator=(const QHash<Key, T> &other)

将other 赋值给此哈希,并返回对此哈希的引用。

T &QHash::operator[](const Key &key)

返回与key 关联的值,并将其作为可修改引用返回。

如果哈希中不存在具有key 的项,则该函数会将一个通过默认构造创建的值插入到哈希中,其键为key ,并返回对该值的引用。

警告: 下次在哈希上调用非 const 函数时,或者当哈希被销毁时,返回的 迭代器/引用将被视为失效。

另请参阅 insert() 和value()。

[noexcept] const T QHash::operator[](const Key &key) const

与value()相同。

这是一个重载函数。

相关的非成员函数

[since 6.1] template < typename Key, typename T, typename Predicate > qsizetype erase_if(QHash<Key, T> &hash, Predicate pred)

从哈希表hash 中移除所有满足谓词pred 的元素。

该函数支持接受类型为QHash<Key, T>::iterator 或std::pair<const Key &, T &> 的谓词。

返回被移除的元素数量(如有)。

该函数在 Qt 6.1 中引入。

[constexpr noexcept, since 6.5] template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = true> size_t qHash(Enum key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

注意:在 Qt 6.5之前, 由于会隐式转换为底层整数类型,无作用域枚举依赖于该函数的整数重载。对于有作用域的枚举,您必须自行实现重载。这仍然是为了保持与旧版 Qt 兼容而采取的向后兼容修复方案。

该函数在 Qt 6.5 中引入。

[noexcept, since 6.0] size_t qHash(QByteArrayView key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数在 Qt 6.0 中引入。

[constexpr noexcept] size_t qHash(uchar key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(uint key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(ulong key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(ushort key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept, since 6.0] size_t qHash(wchar_t key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数于 Qt 6.0 中引入。

[noexcept] size_t qHash(QDate key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[noexcept] size_t qHash(QLatin1StringView key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[noexcept, since 6.0] size_t qHash(QPoint key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数在 Qt 6.0 中引入。

[noexcept] size_t qHash(QTime key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept, since 6.9] template <typename T, std::enable_if_t<std::is_same_v<T, bool>, bool>> size_t qHash(T key, size_t seed)

返回key 的哈希值,并使用seed 作为计算的种子。

注意:这是 qHash(bool) 的重载,仅接受 bool 类型的参数,不接受仅能转换为 bool 的其他类型的参数。

注意:在 Qt 6.9 之前的版本中,该重载曾由一个未记录的 1 到 2 个参数的 qHash 适配器模板函数意外提供,其行为与本函数完全一致。

该函数于 Qt 6.9 中引入。

[constexpr noexcept] size_t qHash(char key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept, since 6.0] size_t qHash(char16_t key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数在 Qt 6.0 中引入。

[constexpr noexcept, since 6.0] size_t qHash(char32_t key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数在 Qt 6.0 中引入。

[constexpr noexcept, since 6.0] size_t qHash(char8_t key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数于 Qt 6.0 中引入。

[noexcept] size_t qHash(const QBitArray &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的初始值。

[noexcept] size_t qHash(const QByteArray &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(const QChar key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

size_t qHash(const QDateTime &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[noexcept(...)] template <typename Key, typename T> size_t qHash(const QHash<Key, T> &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的初始值。

Key 和T 这两种类型必须被 qHash() 支持。

注意: 当noexcept(qHash(std::declval<Key&>())) && noexcept(qHash(std::declval<T&>())) 为true 时,此 函数为 noexcept。

[noexcept(...)] template <typename T> size_t qHash(const QSet<T> &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

T 类型必须被 qHash() 支持。

该哈希值与key 中元素的顺序无关,也就是说,包含相同元素的集合将生成相同的哈希值。

注意: 当noexcept(qHashRangeCommutative(key.begin(), key.end(), seed)) 为true 时,此 函数为 noexcept。

[noexcept] size_t qHash(const QString &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的初始值。

[since 6.0] size_t qHash(const QTypeRevision &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数于 Qt 6.0 中引入。

[noexcept] size_t qHash(const QUrl &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

size_t qHash(const QVersionNumber &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[noexcept] template <typename T> size_t qHash(const T *key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept(...), since 6.12] template <typename T> size_t qHash(const std::optional<T> &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

qHash() 必须支持T 类型。

这等同于

key ? qHash(*key, seed) : qHash(std::nullopt, seed);

特别是,如果启用了key (has_value() ),则保证key 的哈希值与key.value() 的哈希值相同,且所有已禁用(!has_value() )的可选项,无论其类型如何,都会哈希为相同的值。

该函数在 Qt 6.12 中引入。

注意: 当QHashPrivate::noexceptPairHash<T, T>() 为true 时,此 函数为 noexcept。

另请参阅 qHash (std::nullopt_t, size_t)。

[noexcept(...)] template <typename T1, typename T2> size_t qHash(const std::pair<T1, T2> &key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

T1 和T2 这两种类型必须被 qHash() 支持。

注意: 当QHashPrivate::noexceptPairHash<T1, T2>() 为true 时,此 函数为 noexcept。

[noexcept] size_t qHash(double key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[noexcept] size_t qHash(float key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(int key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的初始值。

[constexpr noexcept] size_t qHash(long key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[noexcept] size_t qHash(long double key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的初始值。

[constexpr noexcept, since 6.8] size_t qHash(qint128 key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

注意:此函数 仅在支持原生 128 位整数类型的平台上可用。

该函数于 Qt 6.8 版本中引入。

[constexpr noexcept] size_t qHash(qint64 key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept, since 6.8] size_t qHash(quint128 key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

注意:此函数 仅在支持原生 128 位整数类型的平台上可用。

该函数在 Qt 6.8 中引入。

[constexpr noexcept] size_t qHash(quint64 key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(short key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept] size_t qHash(signed char key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

[constexpr noexcept, since 6.0] size_t qHash(std::nullptr_t key, size_t seed = 0)

返回key 的哈希值,并使用seed 作为计算的种子。

该函数自 Qt 6.0 起引入。

[noexcept] size_t qHashBits(const void *p, size_t len, size_t seed = 0)

返回由 `p` 指向的、大小为 `len ` 的内存块的哈希值,并使用 `seed ` 作为计算的种子。

仅在为自定义类型实现qHash() 时使用此函数。例如,以下是针对 std::vector<int> 实现qHash() 重载的方法:

inline size_t qHash(const std::vector<int> &key, size_t seed = 0)
{
    if (key.empty())
        return seed;
    else
        return qHashBits(&key.front(), key.size() * sizeof(int), seed);
}

这利用了 std::vector 将其数据连续布局这一特性。如果情况并非如此,或者所包含的类型有填充,则应改用qHashRange()。

需要再次强调的是,qHashBits() 的实现——就像 Qt 提供的qHash() 重载一样——可能会随时发生变化。您绝不能依赖 qHashBits() 在不同 Qt 版本中(对于相同的输入)会返回相同结果这一事实。

另请参阅 qHashRange() 和qHashRangeCommutative()。

[constexpr noexcept(...), since 6.0] template <typename... T> size_t qHashMulti(size_t seed, const T &... args)

返回args 的哈希值,使用seed 作为计算种子,通过依次对每个元素应用qHash(),并将各哈希值合并为一个最终值。

请注意,参数的顺序至关重要。如果顺序无关紧要,请改用qHashMultiCommutative()。如果要对原始内存进行哈希处理,请使用qHashBits();如果要对一个范围进行哈希处理,请使用qHashRange()。

提供此函数是为了方便您为自定义类型实现 `qHash()`。例如,以下是您如何为类 `Employee` 实现 `qHash()` 重载的方法:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

class Employee
{
public:
    Employee() {}
    Employee(const QString &name, QDate dateOfBirth);
    QString name() const { return myName; }
    QDate dateOfBirth() const { return myDateOfBirth; }
    //...

private:
    QString myName;
    QDate myDateOfBirth;
};

inline bool operator==(const Employee &e1, const Employee &e2)
{
    return e1.name() == e2.name()
           && e1.dateOfBirth() == e2.dateOfBirth();
}

inline size_t qHash(const Employee &key, size_t seed)
{
    return qHashMulti(seed, key.name(), key.dateOfBirth());
}

#endif // EMPLOYEE_H

该函数在 Qt 6.0 中引入。

注意: 当std::conjunction_v<QtPrivate::QNothrowHashable<T>...> 为true 时,此 函数为 noexcept。

另请参阅 qHashMultiCommutative 和qHashRange 。

[constexpr noexcept(...), since 6.0] template <typename... T> size_t qHashMultiCommutative(size_t seed, const T &... args)

返回args 的哈希值,使用seed 作为计算种子,通过依次对每个元素应用qHash(),并将各哈希值合并为一个最终值。

参数的顺序无关紧要。如果顺序确实重要,请改用 `qHashMulti()`,因为它可能产生更高质量的哈希结果。如果要对原始内存进行哈希,请使用 `qHashBits()`;如果要对一个范围进行哈希,请使用 `qHashRange()`。

提供此函数是为了方便您为自定义类型实现 `qHash()` 函数。

该函数于 Qt 6.0 中引入。

注意: 当std::conjunction_v<QtPrivate::QNothrowHashable<T>...> 为true 时,此 函数为 noexcept。

另请参阅 qHashMulti 和qHashRange 。

[noexcept(...)] template <typename InputIterator> size_t qHashRange(InputIterator first, InputIterator last, size_t seed = 0)

返回范围 [first,last) 的哈希值,使用seed 作为计算种子,通过依次对每个元素应用qHash(),并将各哈希值合并为一个值。

该函数的返回值取决于该范围中元素的顺序。这意味着

{0, 1, 2}

和

{1, 2, 0}

哈希为不同的值。如果顺序无关紧要(例如在哈希表中),请改用qHashRangeCommutative()。若对原始内存进行哈希处理,请使用qHashBits()。

仅将此函数用于为自定义类型实现 `qHash()`。例如,以下是针对 `std::vector<int>` 实现 `qHash()` 重载的方法:

inline size_t qHash(const std::vector<int> &key, size_t seed = 0)
{
    return qHashRange(key.begin(), key.end(), seed);
}

需要再次强调的是,qHashRange() 的实现——就像 Qt 提供的qHash() 重载一样——可能会随时发生变化。即使元素类型的qHash() 在不同 Qt 版本中结果一致,你也绝不能依赖 qHashRange() 在不同 Qt 版本中(对于相同的输入)会返回相同结果这一事实。

注意: 当noexcept(qHash(*first, 0)) 为true 时,该 函数为 noexcept。

另请参阅 qHashBits() 和qHashRangeCommutative()。

[noexcept(...)] template <typename InputIterator> size_t qHashRangeCommutative(InputIterator first, InputIterator last, size_t seed = 0)

返回范围 [first,last) 的哈希值,使用seed 作为计算种子,通过依次对每个元素应用qHash(),并将各哈希值合并为一个值。

该函数的返回值不依赖于该范围中元素的顺序。这意味着

{0, 1, 2}

和

{1, 2, 0}

哈希结果相同。如果顺序很重要(例如对于向量和数组),请改用qHashRange()。若对原始内存进行哈希,请使用qHashBits()。

仅将此函数用于为自定义类型实现 `qHash()`。例如,以下是您可以为 `std::unordered_set<int>` 实现 `qHash()` 重载的方法:

inline size_t qHash(const std::unordered_set<int> &key, size_t seed = 0)
{
    return qHashRangeCommutative(key.begin(), key.end(), seed);
}

需要再次强调的是,qHashRangeCommutative() 的实现——与 Qt XML 提供的qHash() 重载一样——可能会随时发生变化。 即使针对该元素类型的 `qHash()` 在不同 Qt 版本中返回相同结果,你也绝不能依赖 `qHashRangeCommutative()` 在不同 Qt 版本中(对于相同的输入)会返回相同结果这一事实。

注意: 当noexcept(qHash(*first, 0)) 为true 时,该 函数为 noexcept。

另请参阅 qHashBits() 和qHashRange()。

[noexcept] bool operator!=(const QHash<Key, T> &lhs, const QHash<Key, T> &rhs)

如果lhs 哈希值与rhs 哈希值不相同,则返回true ;否则返回false 。

如果两个哈希表包含相同的 (键, 值) 对,则认为它们相等。

此函数要求值类型实现operator==() 。

另请参阅 operator==()。

template <typename Key, typename T> QDataStream &operator<<(QDataStream &out, const QHash<Key, T> &hash)

将哈希hash 写入流out 。

此函数要求键和值的类型都实现operator<<() 接口。

另请参阅 《Qt 数据类型的序列化》。

[noexcept] bool operator==(const QHash<Key, T> &lhs, const QHash<Key, T> &rhs)

如果lhs 哈希与rhs 哈希相等,则返回true ;否则返回false 。

如果两个哈希表包含相同的 (键, 值) 对,则认为它们相等。

此函数要求值类型实现operator==() 。

另请参阅 operator!=()。

template <typename Key, typename T> QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash)

从流in 中读取哈希,并将其写入hash 。

此函数要求键和值的类型都实现operator>>() 接口。

另请参阅 《Qt 数据类型的序列化》。

宏文档

[since 6.11] QT_NO_SINGLE_ARGUMENT_QHASH_OVERLOAD

定义此宏将禁用对仅接受一个参数的qHash 重载的支持;换言之,即针对不接受初始化值的qHash 重载。对qHash 单参数重载的支持已被废弃,并将在Qt 7中移除。

该宏于 Qt 6.11 中引入。

另请参阅 qHash 。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.