2

I'm trying to create following unordered_map:

std::unordered_map<CString, CString, std::function<size_t(const CString &data)>> usetResponse(100, [](const CString &data)
    {
        return std::hash<std::string>()((LPCSTR)data);
    });

I provided hash function for CString, but compiler still returns errors:

error C2338: The C++ Standard doesn't provide a hash for this type. 

error C2664: 'std::unordered_map<CString,CString,std::hash<_Kty>,std::equal_to<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>>::unordered_map(std::initializer_list<std::pair<const _Kty,_Ty>>,unsigned int,const std::hash<_Kty> &,const _Keyeq &,const std::allocator<std::pair<const _Kty,_Ty>> &)' : cannot convert argument 1 from 'std::unordered_map<CString,CString,std::function<size_t (const CString &)>,std::equal_to<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>>' to 'const std::unordered_map<CString,CString,std::hash<_Kty>,std::equal_to<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>> &'

Please tell me what I'm doing wrong ?

drewpol
  • 589
  • 1
  • 4
  • 21
  • What happens if you pass a non-lambda hash function? Same error? – Gillespie Jan 09 '18 at 21:42
  • Please edit your question to contain [mcve] – Slava Jan 09 '18 at 21:45
  • Read the error message more carefully: "*cannot convert argument 1 from 'std::unordered_map,...>' to 'const std::unordered_map,...> &*"'. That means you are trying to pass an instance of your custom `unordered_map` type to a function parameter taking a standard `unordered_map` type. Template parameters are part of the class type, so you can't mix types that use different template parameters. You need to write a specialization of `std::hash` instead of using a custom hash as the template parameter – Remy Lebeau Jan 09 '18 at 21:56
  • Is there any reason to not use CMapStringToString ? https://msdn.microsoft.com/en-us/library/ddw782e0.aspx – Flaviu_ Jan 10 '18 at 09:10
  • This object needs to be returned by function but MFC containers doesn't have default copy-ctor. In this case I don't want to create wrapper for this purpose. – drewpol Jan 10 '18 at 12:02

1 Answers1

3

Something like this:

struct CStringHash
{
    size_t operator () (const CString &s) const
    {
        return hash<string>()(static_cast<LPCSTR>(s));
    }
};

Then declare the map like this:

unordered_map<CString, CString, CStringHash> map;
Sid S
  • 5,907
  • 2
  • 16
  • 23