使嵌套类型哈希能够用于std::unordered_set

Make nested type hash-able for std::unordered_set

本文关键字:unordered set std 用于 嵌套类型 哈希能      更新时间:2023-10-16

我有一个模板structs。结构体foo具有嵌套类型。

template<typename Data>
struct Bar{
};
template<typename Data>
struct Foo {
typedef typename std::pair<Bar<Data>*,Foo<Data>*> Pointers;
std::unordered_set<Pointers> pointers;
};

我想让指针可以散列,适合std::unordered_set<Pointers>

我在这里读到:
如何在无序容器中为用户定义的类型专门化std::hash::operator()?
如何正确散列自定义结构?
boost::hash_combine
模板和嵌套类/结构

并将所有知识结合到这个代码中:

namespace std {
  template <typename Dara> struct hash< typename Foo<Data>::Pointers>
  {
    size_t operator()(const typename Foo<Data>::Pointers & x) const
    {
        std::size_t seed = 0;
        boost::hash_combine(seed, x.first);
        boost::hash_combine(seed, x.second);
        return seed;
    }
  };
}

在最后一段代码中,编译器抛出一个错误:错误:部分专用化中未使用模板参数:Data在这里指向:typename数据。

我尝试从模板中删除数据,并像这样使用它:template <> struct hash< typename Foo::Pointers>但编译器告诉我,它的模板类型错误。

如何更正我的代码?

谨致问候,塔尔。

您不能专门化嵌套类型。编译器无法推断出您要专门化的内容。您可以直接将std::hash<...>专门化为适当的类型,不过:

namespace std {
    template <typename Data>
    struct hash<std::pair<Bar<Data>*,Foo<Data>*>> {
        ...
    }
}

请注意,指针通常不是好的键。您可能需要将*x.first*x.secondhash_combine()一起使用。

我发现了更简单的解决方案:添加boost::hash:

使Foo结构像这样:

template<typename Data>
struct Foo {
typedef typename std::pair<Bar<Data>*,Foo<Data>*> Pointers;
std::unordered_set<Pointers,boost::hash<Pointers> pointers;
};

从这里阅读: