Rei*_*ica 14
将hash实现放在标题中,并确保在使用映射的任何位置包含该标头.
一个简单的实现,转发到qHash应该是足够的:
#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);
}
};
}
Run Code Online (Sandbox Code Playgroud)
即使std::size_t比unsigned int常见的64位平台更大,因此散列不会在其整个长度上发生变化 - 这不是问题.该标准对std::hash实施没有这样的要求.
问题是没有std::hash<QString>()专业化.基于dbj2算法,可以很容易地定义自己的性能并且具有相当好的性能:
#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;
}
};
}
Run Code Online (Sandbox Code Playgroud)
包括在a QString中使用a的文件中,std::unordered_map并且错误消失.