Я программирую класс для работы с пространствами состояний. Моя проблема в том, что я не знаю, каков идеальный способ использовать несколько значений в качестве ключа в unordered_map
,
Это должно работать так:
Я создаю объект состояния со значениями <1; 0; 8>, поэтому он будет вставлен в hashmap как <1;0;8>:pointer_to_object
, Я хочу хэш-карту, потому что мне нужно найти
объекты как можно быстрее.
Я думал об использовании вектор или же кортеж.
Можно ли использовать один из них в качестве ключа для unordered_map
без указания их размера заранее?
Я попытался использовать код, рекомендованный @the_mandrill, следующим образом:
template <class T>
typedef std::unordered_map<std::vector<T>, State<T>*, boost::hash<std::vector<T>> Map;
template <class T>
size_t hash_value(const std::vector<T>& vec)
{
std::size_t seed = 0;
for (const auto& val : vec) {
boost::hash_combine(seed, val);
}
return seed;
}
Но я получаю эту ошибку:
stateSpaceLib.cpp:79:83: error: template argument 3 is invalid
typedef std::unordered_map<std::vector<T>, State<T>*, boost::hash<std::vector<T>> Map;
^
stateSpaceLib.cpp:79:1: error: template declaration of ‘typedef’
typedef std::unordered_map<std::vector<T>, State<T>*, boost::hash<std::vector<T>> Map;
^
Вы должны иметь возможность использовать вектор — либо сам по себе, либо обернуть его в структуру любыми другими данными о состоянии, которые вам нужны, а затем, если у вас есть доступ к boost, используйте hash_combine:
typedef std::unordered_map<std::vector<int>, ObjectPointer, boost::hash<std::vector<int>> Map;
size_t hash_value(const std::vector<int>& vec)
{
std::size_t seed = 0;
for (const auto& val : vec) {
boost::hash_combine(seed, val);
}
return seed;
}
Размер является частью типа для tuple
так что это не сработает.
Но это не так для vector
Таким образом, используя это в качестве ключа должно работать просто отлично.
К сожалению, нет стандартной перегрузки для std:hash
который принимает vector<int>
; Вы могли бы использовать повышение, чтобы восполнить это (http://en.cppreference.com/w/cpp/utility/hash). В качестве альтернативы вы можете предоставить свою собственную хэш-функцию.