我要声明:
std::unordered_map<CString, CString> m_mapMyMap;
但是当我构建时,我得到一个错误,告诉我标准C++没有为CString提供哈希函数,而CString有(LPCSTR)操作符。如何正确地实现CString的哈希函数?
vojdkbi01#
基于std::string的MS STL实现,我创建了可用于std::unordered_set和std::unordered_map的以下方法:
std::string
std::unordered_set
std::unordered_map
namespace std { template <> struct hash<CString> { // hash functor for CString size_t operator()(const CString& _Keyval) const { // hash _Keyval to size_t value by pseudorandomizing transform return (_Hash_seq((const unsigned char*)(LPCWSTR)_Keyval, _Keyval.GetLength() * sizeof(wchar_t))); } }; template <> struct hash<CStringA> { // hash functor for CStringA size_t operator()(const CStringA& _Keyval) const { // hash _Keyval to size_t value by pseudorandomizing transform return (_Hash_seq((const unsigned char*)(LPCSTR)_Keyval, _Keyval.GetLength() * sizeof(char))); } }; }
或者更一般的:
namespace std { template<typename BaseType, class StringTraits> struct hash<CStringT<BaseType, StringTraits>> : public unary_function<CStringT<BaseType, StringTraits>, size_t> { // hash functor for CStringT<BaseType, StringTraits> typedef CStringT<BaseType, StringTraits> _Kty; size_t operator()(const _Kty& _Keyval) const { // hash _Keyval to size_t value by pseudorandomizing transform return (_Hash_seq((const unsigned char*)(StringTraits::PCXSTR)_Keyval, _Keyval.GetLength() * sizeof(BaseType))); } }; }
lnvxswe22#
std::unordered_map使用不使用(LPCSTR)运算符的std::hash〈〉。您需要重新定义哈希函数:
(LPCSTR)
template<class T> class MyHash; template<> class MyHash<CString> { public: size_t operator()(const CString &s) const { return std::hash<std::string>()( (LPCSTR)s ); } }; std::unordered_map<CString,CString,MyHash> m_mapMyMap;
但为了获得更好的性能,请使用std::string代替CString作为key。
lmvvr0a83#
在试用了MrTux's suggestion之后,我不得不说这不再起作用了。std::_HashSeq是removed,std::unary_function在C++17中也被删除了。最后我得到了另一个解决方案,它结合了微软的advice for hash implementations来使用std::basic_string_view的hasher:
std::_HashSeq
std::unary_function
std::basic_string_view
namespace std { template<typename BaseType, class StringTraits> struct hash<ATL::CStringT<BaseType, StringTraits>> { size_t operator()(const ATL::CStringT<BaseType, StringTraits>& key) const noexcept { return hash<basic_string_view<BaseType>>()( basic_string_view<BaseType>( key.GetString(), key.GetLength())); } }; }
xmq68pz94#
首先定义以下内容:
struct KeyHasher { std::size_t operator()(const CString& k) const { using std::hash; using std::string; return hash<string>()(string(CT2CA(k))); } };
然后将其用作哈希函数
std::unordered_map<CString, CString, KeyHasher> umap;
4条答案
按热度按时间vojdkbi01#
基于
std::string
的MS STL实现,我创建了可用于std::unordered_set
和std::unordered_map
的以下方法:或者更一般的:
lnvxswe22#
std::unordered_map使用不使用
(LPCSTR)
运算符的std::hash〈〉。您需要重新定义哈希函数:
但为了获得更好的性能,请使用std::string代替CString作为key。
lmvvr0a83#
在试用了MrTux's suggestion之后,我不得不说这不再起作用了。
std::_HashSeq
是removed,std::unary_function
在C++17中也被删除了。最后我得到了另一个解决方案,它结合了微软的advice for hash implementations来使用
std::basic_string_view
的hasher:xmq68pz94#
首先定义以下内容:
然后将其用作哈希函数