How do I implement a CString hash function for use with std::unordered_map?

后端 未结 2 1656

I want to declare :

std::unordered_map m_mapMyMap;

But when I build I got an error telling me that the standard C++

相关标签:
2条回答
  • 2020-12-11 19:36

    Based on the MS STL implementation for std::string I created the following methods which can be used for std::unordered_set and 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)));
            }
        };
    }
    

    Or even more generic:

    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)));
            }
        };
    }
    
    0 讨论(0)
  • 2020-12-11 19:38

    std::unordered_map use std::hash<> that does not use (LPCSTR) operator.

    You need to redefine hash function:

    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;
    

    But for better performance use std::string instead CString for key.

    0 讨论(0)
提交回复
热议问题