Home > Blockchain >  Hash function for a smart pointer class as key for an unordered map
Hash function for a smart pointer class as key for an unordered map

Time:01-02

So, I have a pointer wrapper class which stores only a pointer and I need to use this class instance as a key in an unordered map. I currently have a similar setup with this pointer wrapper instances as keys to a std::map by overriding bool operator< but for an unordered map setup I would need to override two other operators == and (). I've figured how == operator implementation would be. but not sure about an implementation for the () operator. what sort of hash implementation setup should I be doing in this case? I've checked in places and most examples cover non pointer cases and they use two Key items and form hash for each and compare them for () implementation.

template <class T>
class PointerWrap{
public:
    T* pointer;
    bool operator<(const PointerWrap& other)const{return *pointer < *other.pointer;}
    bool operator==(const PointerWrap& other)const{return *pointer == *other.pointer;}
    //size_t operator()(const PointerWrap& other)const{return (*pointer)(*other.pointer);}
};
class VarType{
    bool operator<(const VarType& other)const{return this < &other;}
    bool operator==(const VarType& other)const{return this == &other;}
    size_t operator()(const VarType& other)(.?.?.}
};
//Desired setup.
std::unordered_map<PointerWrap<VarType>,Value> mymap;

CodePudding user response:

Since you seem to need a hash function only for using PointerWrappers in an unordered map, the hash function in the standard library should serve you well. (But these are not cryptographically secure hash functions so don't use them for anything else). Here is some code to show how to do this:

#include <unordered_map>
#include <iostream>

template <class T>
class PointerWrap {
public:
    T* pointer;
    bool operator<(const PointerWrap& other)const { return *pointer < *other.pointer; }
    bool operator==(const PointerWrap& other)const { return *pointer == *other.pointer; }
    size_t operator()(const PointerWrap& other) const {return (*pointer)(*other.pointer);}
};
class VarType {
public: // PointerWrap has no access to these operators without a public access specifier
    bool operator<(const VarType& other)const { return this < &other; }
    bool operator==(const VarType& other)const { return this == &other; }

    // Pointless to hash a object without any data
    std::size_t operator()(const VarType& other)const {
        return 0;
    }
};

// Specialization of std::hash for PointerWrap<T>
template<typename T>
class std::hash<PointerWrap<T>> {
public:
    size_t operator()(PointerWrap<T> v) const{
        return std::hash<T*>()(v.pointer);
    }
};

int main() {
    // your desired setup compiles.
    std::unordered_map<PointerWrap<VarType>, int> mymap;
    PointerWrap<VarType> a;
    mymap[a] = 5;
    std::cout << mymap[a] << std::endl;
    return 0;
}
  • Related