2

I'm programming the class for working with state-spaces. My problem is, that I don't know, what's the ideal way to use multiple values as a key in unordered_map.


It's supposed to work this way:

I create the state object with values <1;0;8>, so it'll be inserted into the hashmap as <1;0;8>:pointer_to_object. I want the hashmap because I need to find objects as fast as possible.


I thought about using vector or tuple.

Is it possible to use one of them as a key for unordered_map without specifying their size in advance?


EDIT:

I've tried to use the code recommended by @the_mandrill like this:

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;
}

But I'm getting this error:

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;
 ^
Community
  • 1
  • 1
Eenoku
  • 2,741
  • 4
  • 32
  • 64

2 Answers2

1

You should be able to use a vector - either on its own or wrap it in a struct with any other state data you need, and then if you have access to boost then use 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;
 }
the_mandrill
  • 29,792
  • 6
  • 64
  • 93
0

The size is part of the type for tuple, so it wouldn't work.

But that's not the case for vector, so using that as the key should work just fine.

Unfortunately there is no standard overload for std:hash that accepts a vector<int>; you might be able to use boost to make up for this (http://en.cppreference.com/w/cpp/utility/hash). Alternatively you can provide your own hash function.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64