-1

我想使用 astd::string作为 a 的键QHash

QHash<std::string, QString> m_hash;
m_hash.insert("ABC", "DEF");

我实现了所需的 qHash:

inline qHash(const std::string& key, uint seed = 0)
{
  qHash(QByteArray::fromRawData(key.data(), key.length()), seed);
}

一切都使用 MSVC 正确编译,但 gcc 生成以下错误:

错误:没有匹配的调用函数qHash(const std::__cxx11::basic_string<char>&)

我应该如何解决这个问题?

4

1 回答 1

0

简短的回答

  • Qt 6.1 及更新版本

std::string开箱即用支持用作键,因为Qt现在std::hash用作.qHash

  • Qt 6.1 之前

在命名空间内定义qHash函数std可能会解决编译器错误,但将函数添加到std命名空间是未定义的行为所以,这是不允许的。

一种解决方法是包装std::string在一个辅助类[1]中:

class MyHashString : public std::string {};
QHash<MyHashString, QString> m_hash;
m_hash.insert("ABC", "DEF");

inline qHash(const MyHashString& key, uint seed = 0)
{
  qHash(QByteArray::fromRawData(key.data(), key.length()), seed);
}

长答案

如本错误报告qHash中所述,必须在以下名称空间内定义函数std::string

这记录在 C++ 标准中。它称为参数依赖查找。它说搜索不合格的 qHash(T) 会在 T 的命名空间中找到它。

因此,所需的正确定义qHash是:

namespace std
{
  inline qHash(const std::string& key, uint seed = 0)
  {
    qHash(QByteArray::fromRawData(key.data(), key.length()), seed);
  }
}

Qt 文档中也提到了它:

QHash 的键类型除了是可分配的数据类型之外还有其他要求:它必须提供 operator==(),并且类型的命名空间中还必须有一个 qHash() 函数,该函数返回键类型参数的哈希值.

但是,将函数添加到std命名空间是未定义的行为因此,使用一种非理想的解决方法被卡住了。

进一步阅读

于 2020-01-25T14:51:02.710 回答