Using QString as the key in std::unordered_map
Put the hash
implementation in a header, and make sure that you include that header everywhere the map is used.
A trivial implementation that forwards to qHash
should be sufficient:
#include <QHash>
#include <QString>
#include <functional>
namespace std {
template<> struct hash<QString> {
std::size_t operator()(const QString& s) const noexcept {
return (size_t) qHash(s);
}
};
}
Even though std::size_t
is larger than unsigned int
on common 64 bit platforms, and thus the hash doesn't change across its full length - this isn't a problem. The standard places no such requirement on an std::hash
implementation.
The problem is that there is no std::hash<QString>()
specialization. It's easy enough to define your own with reasonably good performance based on the dbj2 algorithm:
#include <QString>
#include <unordered_map>
namespace std
{
template<> struct hash<QString>
{
std::size_t operator()(const QString& s) const noexcept
{
const QChar* str = s.data();
std::size_t hash = 5381;
for (int i = 0; i < s.size(); ++i)
hash = ((hash << 5) + hash) + ((str->row() << 8) | (str++)->cell());
return hash;
}
};
}
include that in files which use a QString
in a std::unordered_map
and the error goes away.