智能指针的哈希函数 class 作为无序映射的键

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

所以,我有一个指针包装器 class,它只存储一个指针,我需要使用这个 class 实例作为无序映射中的键。我目前有一个类似的设置,通过覆盖 bool operator< 使用此指针包装器实例作为 std::map 的键,但对于无序映射设置,我需要覆盖其他两个运算符 ==().我已经知道 == 运算符的实现方式。但不确定 () 运算符的实现。在这种情况下我应该做什么样的哈希实现设置?我检查了一些地方,大多数示例都涵盖了非指针情况,它们使用两个关键项并为每个项形成散列,并比较它们以实现 ()

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;

由于您似乎只需要一个散列函数来在无序映射中使用 PointerWrappers,标准库中的散列函数应该可以很好地满足您的需求。 (但这些不是加密安全的散列函数,所以不要将它们用于任何其他用途)。下面是一些代码来展示如何做到这一点:

#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;
}