我正在尝试使用 QString
作为 std::unordered_map
中的键,但是我得到了错误:
error C2280: 'std::hash<_Kty>::hash(const std::hash<_Kty> &)': attempting to reference a deleted function
我无法切换到 QHash
,因为映射的值类型是不可复制的。有什么方法可以使它起作用吗?
最佳答案
将 hash
实现放在 header 中,并确保在使用 map 的所有地方都包含该 header 。
转发到 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);
}
};
}
即使 std::size_t
在常见的 64 位平台上大于 unsigned int
,因此散列在其全长上不会改变 - 这不是没问题。该标准对 std::hash
实现没有这样的要求。
不过,我们不要忘记,修改 std
命名空间中的任何内容通常是未定义的行为并且是不必要的。
长话短说:
您可以特化某些类型 和变量 模板,并且仅当特化依赖于至少一种用户定义的类型时。您不能完全专注于内置或 C++ 库类型。
参见 Extending the namespace std以供引用。在那里,我们读到:
It is undefined behavior to add declarations or definitions to namespace std or to any namespace nested within std, with a few exceptions noted below.
主要是,允许在 std
命名空间中特化某些类型:
It is allowed to add template specializations for any standard library class template to the namespace std only if the declaration depends on at least one program-defined type and the specialization satisfies all requirements for the original template, except where such specializations are prohibited.
请注意,合法的是专门化类型,即类。函数和成员函数?从来没有:
It is undefined behavior to declare a full specialization of any standard library function template, [... or] member function of a standard library class template, [... or] member function template of a standard library class or class template.
另一个有限的异常(exception)是变量模板:
It is undefined behavior to declare a full or partial specialization of any standard library variable template, except where explicitly allowed.
在所有情况下都强调我的。一如既往,还有更多details that one should get acquainted with .
关于c++ - 使用 QString 作为 std::unordered_map 中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48526115/