I have defined a class that needs to go into unordered_set
and unordered_map
so it needs a hash function. As per How to specialize std::hash for type from other library I'm trying to do this with a std::hash
specialization. The problem I'm running into is that my class, val
, is a recursive type that can contain other val
s and needs to calculate a hash from the hashes of the component values.
I've got this far:
inline void hashCombine(size_t &h, size_t x) {
h ^= x + 0x9e3779b9 + (h << 6) + (h >> 2);
}
namespace std {
template <> struct hash<val> {
size_t operator()(const val &a) const {
if (!a.boxed())
return a.n;
size_t h = 0;
for (auto i : a)
hashCombine(h, hash<size_t>(a[i]));
return h;
}
};
(where a[i]
is a val
)
And get this error message:
./val.h(179,22): error: no matching conversion for functional-style cast from 'val' to 'hash<size_t>' (aka 'hash<unsigned long long>')
hashCombine(h, hash<size_t>(a[i]));
^~~~~~~~~~~~~~~~~
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\type_traits(2178,8): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'val' to
'const std::hash<unsigned long long>' for 1st argument
struct hash
^
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\type_traits(2178,8): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'val' to
'std::hash<unsigned long long>' for 1st argument
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\type_traits(2178,8): note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was
provided
I have also seen example usages that add an extra ()
to the line in question - it seems an odd thing for there to be disagreement about, but okay - which would make it
hashCombine(h, hash<size_t>()(a[i]));
When I try that, I get a different error message:
./val.h(179,23): error: no matching function for call to object of type 'hash<size_t>' (aka 'hash<unsigned long long>')
hashCombine(h, hash<size_t>()(a[i]));
^~~~~~~~~~~~~~
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\type_traits(2161,23): note: candidate function not viable: no known conversion from 'val' to 'const unsigned long long' for 1st argument
_NODISCARD size_t operator()(const _Kty& _Keyval) const
This is one of those times when I'm not sure whether I'm making a trivial syntax error, trying to do something that for fundamental reasons cannot be done, or anywhere in between.
What am I missing?
Aucun commentaire:
Enregistrer un commentaire