Как получить unordered_multimap из unordered_multimaps
Я практиковался в unordered_multimaps и столкнулся с проблемой наличия unordered_multimap, содержащего другое unordered_multimap. Компилятор выдает ошибку, говоря, что стандарт C++ не предоставляет хэш этого типа. Я предполагаю, что мне нужно написать хеш-функцию, но мое понимание ограничено, так как Я новичок в STL.
Я уже пробовал что-то вроде вставки структуры или другой мультикарты в unordered_multimap, но пока не повезло.
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
Как мне реализовать это. То, чего я пытаюсь достичь, - это имя одного человека, связанное с датой рождения и датой его смерти. Я надеялся поместить даты на одной карте и сопоставить их с именем в m_Map2.
1 ответ
Ваша проблема в том, что нет специализации std::hash
доступны для CString
Если свести проблему к ее простейшей части, это также не скомпилирует:
std::unordered_multimap<CString , int> m_Map2;
Потому что std::unordered_multimap<CString, anything>
требует, чтобы существовал класс std::hash<CString>
которая обеспечивает std::size_t operator()(CString const&) const
(это также требует реализации std::equal_to<CString>
но это автоматически доступно, если CString
опоры operator==
,
Вы можете создать такой класс и легально внедрить его в пространство имен std:
#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;