c++ - 使用 QString 作为 std::unordered_map 中的键

标签 c++ qt c++17 stdhash

我正在尝试使用 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/

相关文章:

c++ - 使用 long double 还是仅使用 double 来计算 pi?

c++ - 帮助优化此索引到行列,反之亦然算法

c++ - OpenGL如何反向透视?

c++ - 使用 Qt C++ 截屏

c++ - 为什么按值传递 QStringView 比引用常量更快?

C++初始化对映射

c++ - 如何更改另一个 qml 文件的标签文本?

c++ - 重载派生类的赋值运算符的正确方法是什么?

c++ - 无法从 'auto' 推断出 'tuple_cat'

c++ - 迭代元组 vector c+17 样式不起作用?