Как реализовать хеш-функцию CString для использования с картой std::unordered?
Я хочу объявить :
std::unordered_map<CString, CString> m_mapMyMap;
Но при сборке я получил сообщение об ошибке, говорящее мне, что стандартный C++ не предоставляет хэш-функцию для CString, в то время как CString имеет оператор (LPCSTR).
Как правильно реализовать хэш-функцию для CString?
2 ответа:
Std:: unordered_map использует 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 для ключа.
На основе реализации MS STL для
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))); } }; }