Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

unordered_set from own type by overloading operator() fails

What’s wrong with the operator() inside Entity (hasher) ?

Copy-pasting it to a separate struct works :

#include <bitset>
#include <unordered_map>
using namespace std;

struct Entity {
  
  string name;
  
  size_t operator()(const Entity& k) const noexcept 
  { return std::hash<string>{}(k.name); }
  
  bool operator== (const Entity& e) const noexcept 
  { return e.name == name; }

};

struct KeyHasher {
  size_t operator()(const Entity& k) const noexcept
  { return std::hash<string>{}(k.name); }
};

int main(){
 // unordered_map<const Entity, bitset<24>, KeyHasher> m1; // OK
 unordered_map<const Entity, bitset<24>> m2; // unordered_map() ill-formed ?
  return 0;
}

Error :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<source>: In function 'int main()':
<source>:25:43: error: use of deleted function 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map() 
[with _Key = const Entity; _Tp = std::bitset<24>; _Hash = std::hash<const Entity>; _Pred = std::equal_to<const Entity>; _Alloc = std::allocator<std::pair<const Entity, std::bitset<24> > >]'
   25 |   unordered_map<const Entity, bitset<24>> m2;
      |                                           ^~
In file included from /opt/compiler-explorer/gcc-cxx-modules-trunk-20220427/include/c++/11.0.0/unordered_map:47,
                 from <source>:3:
/opt/compiler-explorer/gcc-cxx-modules-trunk-20220427/include/c++/11.0.0/bits/unordered_map.h:141:7: note: 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map() [with _Key = const Entity; _Tp = std::bitset<24>; _Hash = std::hash<const Entity>; _Pred = std::equal_to<const Entity>; _Alloc = std::allocator<std::pair<const Entity, std::bitset<24> > >]'
 is implicitly deleted because the default definition would be ill-formed:
  141 |       unordered_map() = default;

run

>Solution :

If you don’t specify a hash function for your map it defaults to std::hash<Key> with your key type.
So you will need to define this specialization of std::hash

template<>
struct std::hash<const Entity>
{
    std::size_t operator()(const Entity const& k) const noexcept
    {
        return std::hash<string>{}(k.name);
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading