Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pair<int,int> pair as key of unordered_map issue

My code:

 typedef pair<int,int> Pair
  tr1::unordered_map<Pair,bool> h;
  h.insert(make_pair(Pair(0,0),true));

Erorr

 undefined reference to `std::tr1::hash<std::pair<int, int> >::operator()(std::pair<int, int>) const'

Something I need to fix?

thanks

like image 573
icn Avatar asked Feb 02 '11 03:02

icn


People also ask

Can I use pair as key in unordered_map?

Unordered Map does not contain a hash function for a pair like it has for int, string, etc, So if we want to hash a pair then we have to explicitly provide it with a hash function that can hash a pair.

What is unordered_map int INT?

unordered_map is an associated container that stores elements formed by the combination of key-value and a mapped value. The key value is used to uniquely identify the element and the mapped value is the content associated with the key. Both key and value can be of any type predefined or user-defined.

Can we store pair in unordered set?

An unordered set of pairs is an unordered set in which each element is a pair itself. By default, C++ doesn't allow us to create an unordered set of pairs directly but one can pass a hash function to the unordered set container.

Are pairs hashable in C++?

Using Unordered Data Structures on C++ std::pair However, std::pair is not hashable by default, so a simple snippet like the above would not work.


2 Answers

This happens because there is no specialization for std::tr1::hash<Key> with Key = std::pair<int, int>. You must to specialize std::tr1::hash<Key> with Key = std::pair<int, int> before declaring tr1::unordered_map<Pair,bool> h;. This happens because std don't know how to hash a pair<int, int>.

Following there is a example of how to specialize std::tr1::hash<>

template <>
struct std::tr1::hash<std::pair<int, int> > {
public:
        size_t operator()(std::pair<int, int> x) const throw() {
             size_t h = SOMETHING;//something with x   
             return h;
        }
};
like image 84
Murilo Vasconcelos Avatar answered Oct 11 '22 15:10

Murilo Vasconcelos


Unordered Map does not contain a hash function for a pair, So if we want to hash a pair then we have to explicitly provide it with a hash function that can hash a pair.

If we want to use pair as a key to unordered_map, there are 2 ways to do it :

  1. Define specializaion for std::hash
typedef std::pair<std::string,std::string> pair;

struct pair_hash
{
    template <class T1, class T2>
    std::size_t operator() (const std::pair<T1, T2> &pair) const
    {
        return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
    }
};

int main()
{
    std::unordered_map<pair,int,pair_hash> unordered_map =
    {
        {{"C++", "C++11"}, 2011},
        {{"C++", "C++14"}, 2014},
        {{"C++", "C++17"}, 2017},
        {{"Java", "Java 7"}, 2011},
        {{"Java", "Java 8"}, 2014},
        {{"Java", "Java 9"}, 2017}
    };

    for (auto const &entry: unordered_map)
    {
        auto key_pair = entry.first;
        std::cout << "{" << key_pair.first << "," << key_pair.second << "}, "
                  << entry.second << '\n';
    }

    return 0;
}
  1. Using Boost Library Another good way is to use boost::hash from Boost.functional which can be used to hash integers,floats,pointers,strings,arrays,pairs and theh STL containers.
#include <iostream>
#include <boost/functional/hash.hpp>
#include <unordered_map>
#include <utility>

typedef std::pair<std::string,std::string> pair;

int main()
{
    std::unordered_map<pair,int,boost::hash<pair>> unordered_map =
    {
        {{"C++", "C++11"}, 2011},
        {{"C++", "C++14"}, 2014},
        {{"C++", "C++17"}, 2017},
        {{"Java", "Java 7"}, 2011},
        {{"Java", "Java 8"}, 2014},
        {{"Java", "Java 9"}, 2017}
    };

    for (auto const &entry: unordered_map)
    {
        auto key_pair = entry.first;
        std::cout << "{" << key_pair.first << "," << key_pair.second << "}, "
                  << entry.second << '\n';
    }

    return 0;
}
like image 28
fight_club Avatar answered Oct 11 '22 17:10

fight_club