0

Trying to solve a leetcode problem. Here's the link. In the problem I am trying to make a static map with pair as a key.

As I removed the static keyword, the code is working perfectly fine.

But in case of static keyword, Getting a weird error message like.

In file included from prog_joined.cpp:1:
In file included from ./precompiled/headers.h:34:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/algorithm:71:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/glue_algorithm_defs.h:13:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/functional:61:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/unordered_map:46:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:35:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1382:2: error: static_assert failed due to requirement 'std::__is_invocable<const std::hash<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> &, const std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> &>{}' "hash function must be invocable with an argument of key type"
        static_assert(__is_invocable<const _H1&, const _Key&>{},
        ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:1417:34: note: in instantiation of member function 'std::__detail::_Hash_code_base<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<const std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<int, int>>, std::__detail::_Select1st, std::hash<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::_M_hash_code' requested here
      __hash_code __code = this->_M_hash_code(__k);
                                 ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:921:21: note: in instantiation of member function 'std::_Hashtable<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<const std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<int, int>>, std::allocator<std::pair<const std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<int, int>>>, std::__detail::_Select1st, std::equal_to<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>>, std::hash<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>>::find' requested here
      { return _M_h.find(__x); }
                    ^
Line 18: Char 19: note: in instantiation of member function 'std::unordered_map<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<int, int>, std::hash<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>>, std::equal_to<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>>, std::allocator<std::pair<const std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char>>, std::pair<int, int>>>>::find' requested here
        if(st_end.find({id_stat[id].first,stationName})!=st_end.end()){
                  ^

MySolution :

class UndergroundSystem {
public:
    //   checkIn   map<id,pair<stationName,time>>
    static map<int,pair<string,int>> id_stat;
    
    //   map<pair<startingSt,endingSt>,pair<totalTime,count>>
    static map<pair<string,string>,pair<int,int>> st_end;
    UndergroundSystem() {
        
    }
    
    void checkIn(int id, string stationName, int t) {
        id_stat[id] = {stationName,t};
        
    }
    
    void checkOut(int id, string stationName, int t) {
        if(st_end.find({id_stat[id].first,stationName})!=st_end.end()){
            pair<int,int> s = st_end[{id_stat[id].first,stationName}];
            st_end[{id_stat[id].first,stationName}] = {s.first+ t-id_stat[id].second,s.second+1};
        }else{
            st_end[{id_stat[id].first,stationName}] = {t-id_stat[id].second,1};
        }
        
    }
    
    double getAverageTime(string startStation, string endStation) {
        return (double)st_end[{startStation,endStation}].first/st_end[{startStation,endStation}].second;
    }
};

/**
 * Your UndergroundSystem object will be instantiated and called as such:
 * UndergroundSystem* obj = new UndergroundSystem();
 * obj->checkIn(id,stationName,t);
 * obj->checkOut(id,stationName,t);
 * double param_3 = obj->getAverageTime(startStation,endStation);
 */

Can anybody please explain what is actually going on?

Aarsh
  • 370
  • 1
  • 3
  • 13
  • The error message is complaining about `std::unordered_map`, but the code shown is using `std::map` instead. `std::unordered_map` uses `std::hash` by default to hash keys, but `std::pair` does not have a specialization for `std::hash`. You would have to provide your own hash, or a custom comparator. Otherwise, `std::map` works, because it uses `operator<` instead, which `std:pair` does implement. – Remy Lebeau Apr 24 '22 at 19:43
  • A static variable in a class is initialized at the beginning of the program. The way you have implemented, you have supplied a static qualifier to the maps. You need to initialize the maps before they can be used by the main program. For that you just need to add these two lines after the class definition: `map> UndergroundSystem::id_stat = map>();` `map,pair> UndergroundSystem::st_end = map,pair>();` – Banipreet Singh Raheja Apr 24 '22 at 19:58

0 Answers0