Tal
Tal

Reputation: 1215

Make nested type hash-able for std::unordered_set

I have a template structs. struct foo has nested type.

template<typename Data>
struct Bar{
};

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

I want make Pointers hashable that will fit to std::unordered_set<Pointers>

I read here:
How to specialize std::hash::operator() for user-defined type in unordered containers?
How to properly hash the custom struct?
boost::hash_combine
Templates and nested classes/structures

And combine all the knowledge to this code:

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

At the last piece of code the compiler is throw an error: error: template parameters not used in partial specialization: Data at the point to here: typename Data.

I try to delete the data from template and use it like this: template <> struct hash< typename Foo::Pointers> but the the compiler tell me that it wrong type for template.

How i correct my code?

Regards, Tal.

Upvotes: 0

Views: 656

Answers (2)

Tal
Tal

Reputation: 1215

I found simpler Solution: Add boost::hash:

make Foo struct to be like that:

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

Read from here:

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154015

You cannot specialize on nested types. The compiler can't deduce what you are trying to specialize. You can specialize std::hash<...> for the appropriate type directly, though:

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

Note that pointers generally don't make good keys. You may want to use *x.first and *x.second with hash_combine().

Upvotes: 1

Related Questions