【发布时间】:2016-12-14 14:25:55
【问题描述】:
我需要使用QList<QVariant> 作为std::unordered_map 的密钥。这样做的目的是通过在唯一键列上建立索引来优化对数据表的搜索。
所以我编写了这段代码。不完整,但列出了表键列中出现的一些基本数据类型:
#include <unordered_map>
#include <string>
//std::hash
#include <functional>
//std::size_t
#include <cstddef>
// Hashing method for QVariantList
namespace std {
template <>
struct hash<QList<QVariant>>
{
std::size_t operator()(const QList<QVariant>& k) const
{
using std::size_t;
using std::hash;
using std::string;
size_t hash_num = 0;
Q_FOREACH(var, k) {
// Make hash of the primitive value of the QVariant
switch(var.type()) {
case QVariant::String : {
hash_num = hash_num^hash<string>(var.toString().toStdString());
break;
}
case QVariant::Char :
case QVariant::ULongLong :
case QVariant::UInt :
case QVariant::LongLong :
case QVariant::Int : {
hash_num = hash_num^hash<long long>(var.toLongLong());
break;
}
case QVariant::Double : {
hash_num = hash_num^hash<double>(var.toDouble());
break;
}
}
}
return hash_num;
}
};
}
显然,我不喜欢整个 switch 的东西。这是相当长而丑陋的代码,只考虑基本类型。我宁愿对分配给QVariant 的内部数据的内存数据进行哈希处理。或者,甚至更好 - 使用一些 Qt 的散列方法。
是否有一种半可靠*的方法来散列任何 QVariant 而无需将其转换为原始类型?
*我知道复杂的对象可能隐藏在 QVariant 后面,但这会导致碰撞的情况非常少见,所以我不必在意。
【问题讨论】:
-
你试过Qt的方法
QVariant::toHash()吗? -
@Jean-Emmanuel It looks like 将变体转换为
QHash并且不散列基础值。 -
@Jean-Emmanuel
toHash尝试将QVariant转换为QHash<QString, QVariant>,这是一个哈希映射,而不是一个哈希。我的意思是,是的,我确实在文档上按了 Ctrl+F,另外我还阅读了它所说的内容。 -
如果您不担心性能:使用
QDataStream将QVariant写入QByteArray并使用qHash(const QByteArray &)函数。我还没有看到一种简单的方法来获得QVariant的“原始”表示。 -
你可以使用像this 这样的访问者,然后将返回的值传递给
qHash()。