Compile error defining a std::hash for a template class nested class

galinette

I have a class:

namespace App
{

template<typename A, typename B>
class MyClass
{
    //...
    class NestedClass
    {
        //...
    }
}

} //namespace App  

I would like to define a std::hash for NestedClass

//Definition of hash functions
namespace std
{
    //Definition of a hash to use generic pairs as key
    template<typename A, typename B>
    struct hash<App::MyClass<A,B>::NestedClass>
    {
    public:
        size_t operator()(const App::MyClass<A,B>::NestedClass &it) const
        {
            return std::hash(it.toInt());
        }
    };
}

I get the error:

source.h:1166: error: type/value mismatch at argument 1 in template parameter list for 'template<class _Tp> struct std::hash'
  struct hash<App::MyClass<A,B>::const_NestedClass>
                                                  ^

Any idea? Thanks!

Vittorio Romeo

You can fix your error by adding typename where appropriate to inform the compiler that the symbol following :: is indeed a type:

template<typename A, typename B>
struct hash<typename App::MyClass<A, B>::NestedClass>
{//         ^^^^^^^^
public:
    size_t operator()(const typename App::MyClass<A,B>::NestedClass &it) const
//                          ^^^^^^^^
    {
        return hash(it.toInt());
    }
};

Now you get a new error:

prog.cc:22:12: error: class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used [-Wunusable-partial-specialization]
    struct hash<typename App::MyClass<A, B>::NestedClass>
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:21:23: note: non-deducible template parameter 'A'
    template<typename A, typename B>
                      ^
prog.cc:21:35: note: non-deducible template parameter 'B'
    template<typename A, typename B>

It is impossible for the compiler to deduce A and B in this context, as there's no guarantee that NestedClass exists for all MyClass<A, B> instantiations. More information:

You'll probably be able to work around this by assuming that NestedClass exists and hashing on MyClass<A, B> instead. Provide some way of accessing NestedClassfrom MyClass and you'll be able to write something like this:

template<typename A, typename B>
struct hash<typename App::MyClass<A, B>>
{
public:
    size_t operator()(const typename App::MyClass<A,B> &it) const
    {       
        return hash(it.nested.toInt());
    }
};

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Nested class template specialization

Nested class as a template parameter

Defining a templated friend function inside a template class

error: 'hash' is not a class template

Error : ‘template<class> class std::auto_ptr’ is deprecated

forward declaration of a class template including a namespace causes compile-error

defining inline functions under template class definition

Inherit template class with nested class

Defining nested class conditionally based on enclosing class template parameters

Hash an object using its base class' partial template specialization for std::hash

Defining a class templates constructor and providing the template arguments

Error when using the std::allocator in the template class

defining destructor in a class derived from move-only type gives compile-time error when created with emplace_back or push_back of std::vector

Error for defining class method as expression

std thread call template member function of template class: compiler error

Multiple class compile error

C++ compile error when implementing template class

gcc compiling error: member of nested class A in template class Table is not visible in nested friend class. Why?

Scala error when defining class

Error defining function outside the class

Defining conversion operator for specialized template class only

Resolve template with a nested class

Defining template class member functions in a namespace?

Using std::conditional with is_class<int>, getting compile error

Defining template function with std::is_invocable_v outside of class

Why does introducing std::mutex to member class generate this compile error?

Aliasing a nested class of a template

Redefinition error when defining friend function inside class template

error: nested name specifier for declaration does not refer into a class, class template or class template partial specialization