lo tolmencre
lo tolmencre

Reputation: 3954

Define Hash Template for Nested Types

I need to define a hash function for a type, which depends on a type, which depends on a type. I tired it like this:

I thought, I need to provide a a template parameter for G in the hash function, as otherwise G could not be correctly deduced, as it requires a template parameter itself, but I am getting a warning.

template <typename P>
class G;

template <typename G>
class R;

template <typename P> std::size_t hash_code(const typename R<G<P>>::rs&);




namespace std
{
    template <typename P>
    struct hash<typename R<G<P>>::rs>
    {
        size_t operator()(const typename R<G<P>>::rs& rs) const
        {
            return hash_code(rs);
        }
    };
}



// definitions

template <typename P>
class G
{

public:

    typedef P p;
    typedef G<p> THIS;
    typedef R<THIS> r;

    std::unordered_set<r> Rset;

};



template <typename G>
class R
{

public:

    typedef G g;
    typedef typename G::p rs;

};




template<typename P>
size_t hash_code(const typename R<G<P>>::rs& rs)
{
    size_t hash = 0x9e3779b9;

    // hashing

    return hash;
}

the warning is:

hashtest.cpp:20:12: warning: class template partial specialization contains a template
      parameter that cannot be deduced; this partial specialization will never be used
    struct hash<typename R<G<P>>::rs>
           ^~~~~~~~~~~~~~~~~~~~~~~~~~
hashtest.cpp:19:24: note: non-deducible template parameter 'P'
    template <typename P>

That is the exact issue I wanted to avoid by templating G inside the hash template.

Upvotes: 0

Views: 100

Answers (2)

Jarod42
Jarod42

Reputation: 218148

R<G<P>>::rs is a non-deductible context (due to ::).

And anyway it will result into P which is not a specialization.:

template <typename P> struct hash<P>

Upvotes: 1

dascandy
dascandy

Reputation: 7302

If this is your actual code and not a hand-copy-paste:

struct hash<typename R<G<P>::rs>

You're missing a closing bracket after the P.

Upvotes: 0

Related Questions