It seems as if C++ does not have a hash function for strings in the standard library. Is this true?
What is a working example of using a string as a key in an unordered_map that will work with any c++ compiler?
C++ STL provides template specializations of std::hash for the various string classes. You could just specify std::string as key type for std::unordered_map:
#include <string>
#include <unordered_map>
int main()
{
std::unordered_map<std::string, int> map;
map["string"] = 10;
return 0;
}
std::hash<std::string>> when you already have an std::unordered_map<std::string> is just redundant.-std=c++11), unordered_map is a C++11 feature.std::unordered_map<std::string, int, std::hash<std::string>> map; (the original answer before editing). Here, std::hash<std::string> can be omitted because std::unordered_map is defined as template<class Key, class T, class Hash=std::hash<Key>, ...> class unordered_map;.I ran into this today (actually with wstring, not string, but it's the same deal): using wstring as a key in an unordered_map generates an error about no hash function being available for that type.
The solution for me was to add:
#include <string>
Believe it or not, without the #include directive I still had the wstring type available but apparently NOT the ancillary functions like the hash. Simply adding the include above fixed it.
If you have a CustomType and you want to plug into the STL infrastructure this is what you could do.
namespace std
{
//namespace tr1
//{
// Specializations for unordered containers
template <>
struct hash<CustomType> : public unary_function<CustomType, size_t>
{
size_t operator()(const CustomType& value) const
{
return 0;
}
};
//} // namespace tr1
template <>
struct equal_to<CustomType> : public unary_function<CustomType, bool>
{
bool operator()(const CustomType& x, const CustomType& y) const
{
return false;
}
};
} // namespace std
If you then want to create say a std::unordered_map<CustomType> the STL will find the hash and equal_to functions without you having to do anything more with the template. This is how I like to write my custom equality comparer that support unordered data structures.
In my case it was really distraction.
I had a type X for which I implemented hashing for const& X an utilized it somewhere with
std::unordered_map<const X, int> m_map;
Then I wanted to have another map which key are of the type X and did:
std::unordered_map<X, int> map_x;
Notice the LACK of const on the second case.
unordered_map) didn't support a hash function forstd::string?basic_string<>directly instead of through thestd:stringtypedef? You might be able to usebasic_string<>for some purposes without a compiler error because another header happens to be pulling inxstring(which gives youbasic_string<>, but notstd::hash<string>)#include <string>if you're trying to use strings in anunordered_map<>- actually, any time you're usingstd::string. Unfortunately, the compiler will sometimes let you get away without the include because of side effects from other includes. then when you add a use that actually requires thestringheader you get a mysterious, non-obvious error from the compiler.#include <unordered_map>to#include <bits/unordered_map.h>. So make sure you have included the correct lib.