I was practicing through unordered_multimaps and I came across a problem of having an unordered_multimap containing another unordered_multimap.The compiler throws an error saying c++ standard does not provide hash of this type.I guess I have to write a hash function but my understanding is limited since I am new to STL.
I have already tried something like inserting a struct or another multimap to the unordered_multimap but no luck so far.
std::unordered_multimap<long,long>m_Map1;
std::unordered_multimap<CString,m_Map1>m_Map2; //This line throws
error
//inserting to the map
m_Map1.insert(std::pair<long,long>(10,20));
m_Map2.insert(_T("ABC"),m_Map1);
//also the compiler does not let me create an object for this map
m_Map1 m_ObjMap; //error here as well
How should I implement this.What I am trying to achieve here is one person's Name associated with birthdate and date on which he dies.I was hoping of having the dates in one map and mapping it with name to the m_Map2.
Your problem is that there is no specialisation of std::hash
available for CString
Boiling the problem down to its simplest part, this will also not compile:
std::unordered_multimap<CString , int> m_Map2;
Because std::unordered_multimap<CString, anything>
requires that there exists a class std::hash<CString>
which provides std::size_t operator()(CString const&) const
(it also requires an implementation of std::equal_to<CString>
but this is automatically available if CString
supports operator==
.
You can create such a class and legally inject it into the std namespace:
#include <unordered_map>
#include <boost/functional/hash.hpp> // for boost::hash_range, see below
// for exposition
struct CString
{
const char* data() const;
std::size_t length() const;
bool operator==(CString const& other) const;
};
namespace std
{
// specialise std::hash for type ::CString
template<> struct hash<::CString>
{
std::size_t operator()(CString const& arg) const
{
std::size_t seed = 0;
// perform whatever is your hashing function on arg here
// accumulating the hash into the variable seed
// in this case, we're doing it in terms of boost::hash_range
auto first = arg.data();
auto last = first + arg.length();
boost::hash_range(seed, first, last);
return seed;
}
};
}
std::unordered_multimap<CString , int> m_Map2;