user1529540
user1529540

Reputation:

c++11, why does this unordered_map defined for vector <int> not work?

I am trying to create an unordered_map<vector<int>, int>. I know that I need to have my own hash function, so I tried to build one. I am capable of creating it and compiling it fine, but I get compilation errors when I try to access it.

Here is the code:

#include <bits/stdc++.h>
using namespace std;

class mhash {
public:
  std::size_t operator()(std::vector<int> const& vec) const {
    std::size_t seed = vec.size();
    for(auto& i : vec) {
     seed ^= i + 0x9e3779b9 + (seed << 6) + (seed >> 2);
     }
  return seed;
    }
};

map <vector <int>,int, mhash> M;

int main(){
    vector <int> V;
    M[V]=5;
    cout << M[V];
}

I am compiling using g++ -std=c++11.

If I only declare the unordered_map it compiles fine, but when I try to use it I get the following errors:

In file included from /usr/include/c++/5/map:61:0,
                 from /usr/include/x86_64-linux-gnu/c++/5/bits/stdc++.h:80,
                 from exp.cpp:1:
/usr/include/c++/5/bits/stl_map.h: In instantiation of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::vector<int>; _Tp = int; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::vector<int>]’:
exp.cpp:19:5:   required from here
/usr/include/c++/5/bits/stl_map.h:481:32: error: no match for call to ‘(std::map<std::vector<int>, int, mhash>::key_compare {aka mhash}) (const key_type&, const std::vector<int>&)’
  if (__i == end() || key_comp()(__k, (*__i).first))
                                ^
exp.cpp:6:15: note: candidate: std::size_t mhash::operator()(const std::vector<int>&) const
   std::size_t operator()(std::vector<int> const& vec) const {
               ^
exp.cpp:6:15: note:   candidate expects 1 argument, 2 provided
In file included from /usr/include/c++/5/map:60:0,
                 from /usr/include/x86_64-linux-gnu/c++/5/bits/stdc++.h:80,
                 from exp.cpp:1:
/usr/include/c++/5/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, const _Key&) [with _Key = std::vector<int>; _Val = std::pair<const std::vector<int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::vector<int>, int> >; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::vector<int>, int> >*]’:
/usr/include/c++/5/bits/stl_tree.h:1091:30:   required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::vector<int>; _Val = std::pair<const std::vector<int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::vector<int>, int> >; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = std::vector<int>]’
/usr/include/c++/5/bits/stl_map.h:916:36:   required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::vector<int>; _Tp = int; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::vector<int>]’
/usr/include/c++/5/bits/stl_map.h:479:28:   required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::vector<int>; _Tp = int; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::vector<int>]’
exp.cpp:19:5:   required from here
/usr/include/c++/5/bits/stl_tree.h:1628:6: error: no match for call to ‘(mhash) (const std::vector<int>&, const std::vector<int>&)’
  if (!_M_impl._M_key_compare(_S_key(__x), __k))
      ^
exp.cpp:6:15: note: candidate: std::size_t mhash::operator()(const std::vector<int>&) const
   std::size_t operator()(std::vector<int> const& vec) const {
               ^
exp.cpp:6:15: note:   candidate expects 1 argument, 2 provided

Upvotes: 0

Views: 397

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385108

Because you instantiated a std::map, not an std::unordered_map.

Normal maps don't take hash functions.

Presumably this is just a typo.

By the way, avoid #include <bits/stdc++.h>.

Upvotes: 0

Iv&#225;n
Iv&#225;n

Reputation: 1060

You wrote map, not unordered_map.

But... if you want a map: The third template argument for a map is not a hash, but a comparator. bool operator()(a, b)

Upvotes: 1

Related Questions