Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can not I use operator[] for std::unordered_map<std::pair<int,int>, int> but for same key-value pair of `std::map`? [duplicate]

#include <bits/stdc++.h>

std::unordered_map<std::pair<int,int>, int> mp;

int main()
{
    mp[make_pair(1, 2)]++;
}

When using the [] operator, I get this

error: no match for ‘operator[]’ (operand types are ‘std::unordered_map<std::pair<int, int>, int>’ and ‘std::pair<int, int>’)

However, when doing the same with std::map, no error occurs. why?

How can I make it works with std::unorderd_m?

like image 511
Kavaliro Avatar asked Aug 25 '18 07:08

Kavaliro


Video Answer


1 Answers

when doing the same with std::map, no error occurs. why? And how can I make it works with std::unorderd_map ?

Because they are simply different.

std::unorderd_map the elements are placed according to the hash of its keys.

template<
    class Key,
    class T,
    class Hash = std::hash<Key>,  
    class KeyEqual = std::equal_to<Key>,
    class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;

whereas the std::map needs simply a comparison function in order to sort the keys.

template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class map;

The reason why your std::map<std::pair<int,int>, int> got compiled is, the operator< is defined for std::pair and std::map uses it to sort its keys, whereas the hash function for std::pair has not been defined and hence std::unorderd_map need one to keep elemets in its buckets. This you need to define.

For instance, you can define a custom hash function as follows:

#include <unordered_map>
#include <cstddef>
#include <functional>

struct CustomHash
{
  template <typename T, typename U>
  std::size_t operator()(const std::pair<T, U> &x) const
  {
    return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
  }
};

int main()
{
    std::unordered_map<std::pair<int,int>, int, CustomHash> mp;
    mp[std::make_pair(1, 2)]++;
    return 0;
}

PS: #include <bits/stdc++.h>is a bad coding practice. Why? see this .

like image 144
JeJo Avatar answered Nov 03 '22 21:11

JeJo