Reputation: 13303
What I am trying to do is:
#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;
}
The compiler message is:
error: no matching function for call to 'qHash(const QLinkedList<MyType>::iterator&)'
I know, that the reason why the first three lines compile is that for the QVector
, the iterator is defined as typedef T* iterator;
but for the QLinkedList
it is a custom type.
I found out, that the QSet
template class is implemented in terms of a hash table.
Apparently it is possible to evaluate the hash function for a pointer, but not for a custom type.
Please, could you tell me, how to overload the qHash
function for my program to compile? I have read some basic information on the workings of a hash table, but I lack the confidence in the subject.
I tried to understand the inner workings of the QLinkedList<T>::iterator
. It seems that it is very similar to the QVector<T>::iterator
. It just holds a pointer to a node in the linked list instead of a pointer to the item itself.
class iterator
{
public:
...
Node *i;
...
};
So I tried to define the function in this manner:
uint qHash(QLinkedList<MyType>::iterator it)
{
return qHash(it.i);
}
The program compiled, but I have no confidence in my solution. How should I correctly overload the qHash
function?
Upvotes: 2
Views: 781
Reputation: 14621
You did perfectly well already. The basic rules of hash functions are:
x = y
then hash(x) = hash(y)
.x != y
then hash(x) != hash(y)
(as often as possible). This isn't a strict rule, but the better it's followed, the better the performance of the hash table. Ideally, the outputs will appear random.Your way works because if two iterators, ia
and ib
are equal (referring to the same node), their internal pointers, ia.i
and ib.i
will be equal. That takes care of rule 1. Then you use a built-in hash function on those pointers; Qt takes care of rule 2 for you.
Cheers!
Upvotes: 1