View Full Version : QHash add comparison function, how?
holst
30th March 2010, 08:09
Hi,
In std::map (stl) you can define the key and value types, but also the comparison function for the keys.
I want to do the same for a QHash, but I reading QtAssistant and googling and the only things I can define are key and value type.
Can I set the comparison function for a QHash? If yes, how?
Thanks.
spud
30th March 2010, 08:21
You not only can, but you have to define the function:
quint32 qHash(const Key &key);
unless you're working with some standard type, for which the function already has been provided.
holst
30th March 2010, 09:03
I'm using a QPair as a key, and I want to use another comparison function and not the given one.
I tried to derived QPair an use it as a key:
template <class T1, class T2>
struct stEvPairKey : QPair<T1, T2>
{
stEvPairKey() : QPair<T1, T2>() {}
stEvPairKey(const T1 &t1, const T2 &t2) : QPair<T1, T2>(t1, t2) {}
};
template <class T1, class T2>
bool operator==(const stEvPairKey<T1, T2> &p1, const stEvPairKey<T1, T2> &p2)
{
return (p1.first == p2.first) && (p1.second & p2.second);
}
and use this struct as a key:
QHash<stEvPairKey<int, unsigned long>, CMyClass*> m_hash;
But never goes into my "operator==".
The function you give:
quint32 qHash(const Key &key);
is to compute the hash value for the key, but not to compare 2 keys.
What is wrong?
Thank you.
wysota
30th March 2010, 09:07
Doesn't QPair have the operator already defined the way you defined it?
spud
30th March 2010, 10:14
As you will see in the following program, both the equality operator and the hash function get called.
#include <QHash>
#include <QDebug>
template <class T1, class T2>
struct stEvPairKey : QPair<T1, T2>
{
stEvPairKey() : QPair<T1, T2>() {}
stEvPairKey(const T1 &t1, const T2 &t2) : QPair<T1, T2>(t1, t2) {}
};
template <class T1, class T2>
bool operator==(const stEvPairKey<T1, T2> &p1, const stEvPairKey<T1, T2> &p2)
{
qDebug()<<"comparison";
return (p1.first == p2.first) && (p1.second & p2.second);
}
template <class T1, class T2>
quint32 qHash(const stEvPairKey<T1,T2>&key)
{
qDebug()<<"hash";
return qHash((QPair<T1,T2>)key);
}
void main()
{
QHash<stEvPairKey<int, unsigned long>, bool> m_hash;
m_hash.insert(stEvPairKey<int, unsigned long>(1, 2), true);
if(m_hash.contains(stEvPairKey<int, unsigned long>(1, 2)))
qDebug()<<"true";
}
Although, as Wysota pointed out, both functions are unnecessary because QPair provides those functions.
wysota
30th March 2010, 10:44
By the way... qHash() is for comparing two keys.
holst
30th March 2010, 11:29
ok, at last I understand what is happening.
The second part of the key T2 are some flags. For example this code
#include <QtCore/QCoreApplication>
#include <QMultiHash>
#include <QDebug>
#include <QString>
template <class T1, class T2>
struct stEvPairKey : QPair<T1, T2>
{
stEvPairKey() : QPair<T1, T2>() {}
stEvPairKey(const T1 &t1, const T2 &t2) : QPair<T1, T2>(t1, t2) {}
};
template <class T1, class T2>
bool operator==(const stEvPairKey<T1, T2> &p1, const stEvPairKey<T1, T2> &p2)
{
qDebug()<<"comparison";
return (p1.first == p2.first) && (p1.second & p2.second);
}
template <class T1, class T2>
quint32 qHash(const stEvPairKey<T1,T2>&key)
{
qDebug()<<"hash: " << qHash((QPair<T1,T2>)key);
return qHash((QPair<T1,T2>)key);
}
enum EFlags
{
NONE_FLAGS = 0,
FLAG1 = 1,
FLAG2 = 2,
FLAG3 = 4,
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QHash<stEvPairKey<int, unsigned long>, bool> m_hash;
m_hash.insert(stEvPairKey<int, unsigned long>(1, FLAG1 | FLAG3), true);
if(m_hash.contains(stEvPairKey<int, unsigned long>(1, FLAG1)))
qDebug()<<"FLAG1: true";
if(m_hash.contains(stEvPairKey<int, unsigned long>(1, FLAG1 | FLAG3)))
qDebug()<<"FLAG1 | FLAG3: true";
return a.exec();
}
The output is:
hash: 65541
hash: 65541
hash: 65537
hash: 65541
comparison
FLAG1 | FLAG3: true
My idea was to implement the operator== for stEvPairKey so the 1st "if()" be also true. But as is shown in the output the hash value is different for "FLAG1" and for "FLAG1 | FLAG3".
I was confused, the flags can't be part of the hash key.
Thank you very much :)
wysota
30th March 2010, 13:51
Maybe they should be a part of value and not the key then?
holst
30th March 2010, 15:38
Yes, that's right.
I made the change and works. I was confused, I was only thinking in the comparison function, when "contains()" is called, and no the "qHash()".
Thank you again.
wysota
30th March 2010, 19:49
QHash::contains() will call qHash() for the key.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.