我想做的是:
#include <QVector>
#include <QLinkedList>
#include <QSet>
class MyType
{
//...
};
int main(int argc, char** argv)
{
QVector<MyType> vector;
QSet<QVector<MyType>::iterator> a;
a.insert(vector.begin()); // This is fine
QLinkedList<MyType> linkedList;
QSet<QLinkedList<MyType>::iterator> b;
b.insert(linkedList.begin()); // This does not compile
return 0;
}
编译器消息是:
error: no matching function for call to 'qHash(const QLinkedList<MyType>::iterator&)'
我知道,前三行编译的原因是对于QVector
,迭代器定义为typedef T* iterator;
,但对于QLinkedList
,它是自定义类型。
我发现,QSet
模板类是根据哈希表实现的。
显然,可以评估指针的哈希函数,但不能评估自定义类型。
请你告诉我,如何重载qHash
函数来编译我的程序?我已经阅读了一些关于哈希表工作的基本信息,但我对这个主题缺乏信心。
我试图了解QLinkedList<T>::iterator
的内部运作方式。它似乎与QVector<T>::iterator
非常相似。它只保存指向链表中节点的指针,而不是指向项本身的指针。
class iterator
{
public:
...
Node *i;
...
};
所以我尝试以这种方式定义函数:
uint qHash(QLinkedList<MyType>::iterator it)
{
return qHash(it.i);
}
该程序已编译,但我对我的解决方案没有信心。我应该如何正确地重载qHash
函数?
答案 0 :(得分:1)
你做得非常好。哈希函数的基本规则是:
x = y
则hash(x) = hash(y)
。x != y
则hash(x) != hash(y)
(尽可能频繁)。这不是一个严格的规则,但它遵循的越好,哈希表的性能越好。理想情况下,输出将是随机的。你的方式有效,因为如果两个迭代器ia
和ib
相等(指同一节点),它们的内部指针ia.i
和ib.i
将是相等的。这会处理规则1.然后在这些指针上使用内置的哈希函数; Qt为您处理规则2。
干杯!