What is the best way to calculate the qHash
value of a QRect
? I need to use QRect
(and maybe QRectF
) as the key of QCache
. Right now I am using something like this:
inline uint qHash(const QRect & r)
{
return qHash(QByteArray::fromRawData((const char*)&r, sizeof(r)));
}
It seems to work but I don't like casting it into some raw bytes and since QRect is noy a simple struct, this may break sooner than later in future versions of开发者_如何学Python Qt.
BTW. I don't store the hash values so it doesn't have to be persistent or cross-platform. But it does need to be reliable and fast.
Thanks.
I would simply do return qHash(QString("%1,%2,%3,%4").arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height())))
Also I've found this solution: http://thesmithfam.org/blog/2008/01/17/using-qrect-with-qhash/ (read comment)
Well, how about:
inline uint qHash(const QRect & r)
{
return qHash(r.left()) + qHash(r.top()) + qHash(r.width()) + qHash(r.bottom());
}
What about simply XORing each integer? As far as I know, qHash(QPair<..>) does this (with the already calculated qHashes for both items).
inline uint qHash(const QRect & r)
{
return qHash(r.left() ^ r.top() ^ r.right() ^ r.bottom());
// or
return qHash(r.left()) ^ qHash(r.top()) ^
qHash(r.right()) ^ qHash(r.bottom());
}
The same for QRectF:
inline uint qHash(const QRectF & r)
{
return qHash(r.left()) ^ qHash(r.top()) ^
qHash(r.right()) ^ qHash(r.bottom());
}
(Note that even rounding down to integers does NOT mean that your cache will work improperly - just the hash table "cheats" a bit.)
I think this is most optimal solution for >=Qt5.4:
uint qHash(const QRect& r)
{
int data[4];
data[0] = r.left();
data[1] = r.top();
data[2] = r.width();
data[3] = r.height();
return qHashBits(data, 4 * sizeof(int));
}
For versions of Qt below 5.4 we have to write less optimal in such manner:
uint qHash(const QRect& r)
{
QByteArray data(sizeof(int) * 4, 0);
int* d = reinterpret_cast<int*>(data.data());
d[0] = r.left();
d[1] = r.top();
d[2] = r.width();
d[3] = r.height();
return qHash(data);
}
精彩评论