如何将“ std :: string”用作“ QHash”的键?

时间:2020-01-25 14:51:02

标签: c++ qt qhash

我想使用std::string作为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>&)

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

1 个答案:

答案 0 :(得分:0)

简短答案

qHash名称空间中定义std函数可以解决编译器错误,但是 adding a function to the std namespace is undefined behaviour因此,不允许这样做。

一种解决方法是将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);
}

长期回答

如本bug report所述,必须在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()函数,该函数会返回键类型的参数的哈希值。

但是, adding a function to the std namespace is undefined behaviour。因此,使用一种不理想的解决方法会陷入困境。

进一步阅读

相关问题