Reputation: 9292
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!
Upvotes: 1
Views: 2333
Reputation: 93364
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 NestedClass
from 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());
}
};
Upvotes: 4