Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use std::vector as the type of key for an std::unordered_map in C++?

I'm trying to build an unordered map to contain points in n-dimensional space. I understand that std::vector meets all the requirements for being a key in std::map, and yet this code does not compile. I get a long list of error messages, but this seems the most problematic:

error: no match for call to ‘(const std::hash<std::vector<int> >) (const std::vector<int>&)'.

Does anyone have any idea as to why g++ doesn't seem to think that std::vector<int> is hashable?

#include <vector>
#include <unordered_map>
#include <boost/functional/hash.hpp>

using namespace std;

typedef vector<int> point;

int main()
{
    unordered_map<point, int>jugSpace;
    vector<int> origin(3, 0);

    jugSpace.insert( pair<point,int>(origin, 0) );
}
like image 652
Monty Evans Avatar asked Dec 12 '16 14:12

Monty Evans


2 Answers

Unordered map requires availability of hash function for the key. Such function does not exist for std::vector in standard implementation.

You could use std::map, though - it requires comparison operator, which exists for vector.

If you really must use vector as a key to hash map (which seems dubious), you should implement hashing function yourself.

like image 73
SergeyA Avatar answered Oct 07 '22 12:10

SergeyA


You need to specialize template class std::hash<> for your point like:

namespace std {
  template<>
  class hash<point> {
  public:
    size_t operator()(const point &p) const {
      // put here your hash calculation code
    }  
  };
}

Or create custom hasher class and specify its type as template member for std::unordered_map:

class my_hash {
public:
  size_t operator()(const point &p) const {
    // your hash calculation code
  }
};

// somewhere in your code, where you declare your unordered_map variable
std::unordered_map<point, int, my_hash> myUnorderedMap;

If you want to use boost::hash_value as hash function then just return its result in your hasher implementation, ex:

class my_hash {
public:
  size_t operator()(const point &p) const {
    return boost::hash_value(p);
  }
};
like image 39
Deedee Megadoodoo Avatar answered Oct 07 '22 11:10

Deedee Megadoodoo