2016-02-15 183 views
4

我要声明:如何实现CString哈希函数与std :: unordered_map一起使用?

std::unordered_map<CString, CString> m_mapMyMap; 

但是,当我建立我得到一个错误,告诉我,C++标准没有为CString的提供的哈希函数,而CString的有(LPCSTR)运算符。

如何正确实现CString的哈希函数?

+0

什么是你的问题? – juanchopanza

+0

如何让它编译。 – Aminos

+0

你应该在问题的主体中清楚地说明这一点。无论如何,这是重复的。 – juanchopanza

回答

3

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的关键。

+0

你可以澄清的性能差异? – phant0m

+0

还有将CString转换为const TCHAR ptr的地方,并且比构造anonimous std :: string对象更加容易。没有办法保证const TCHAR ptr指向的内存不会被释放或重写,所以std :: string不能使用那个内存。 std :: string从该内存中复制字符串。所以这个简单的解决方案有无用的内存应对性能问题。没有std api从“char”字符串中取出“C”字符串。因此,在简单情况下,可以使用此解决方案,并且为了获得最佳性能,需要使用std :: string或编写特殊的散列函数。 – oklas

+0

啊,有道理,谢谢! – phant0m

1

基于MS STL实施std::string我创建了以下方法可用于std::unordered_setstd::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))); 
     } 
    }; 
}