Reputation: 22744
In Qt I had the brilliant (cough, cough) idea to start defining overloads of qHash
(the hashing function used for QHash, one of Qt's associative containers) for Standard Library datatypes: std::basic_string
, std::shared_ptr
and the like.
There could be a shortcut for this process: instead of chasing "any Standard Library type that could be used as a key in QHash" and adding a qHash
overload for it, I could just define qHash
automatically if the type has a std::hash
specialization for it (reasonably assuming that we don't want to do more than what the Standard Library does in this process).
That is, I could implement something like this using expression SFINAE:
template<typename T>
auto qHash(const T &t) -> decltype(std::hash<T>()(t))
{
return std::hash<T>()(t);
}
Unfortunately, although Qt demands a C++11 compiler, expression SFINAE is not allowed anywhere because MSVC does not fully support it (at the time of this writing: all MSVC versions, up to and including VS15 preview 5. Anyhow, Qt must support all the way back to 2013).
Hence, the question: is there a way to do the same, in a way that
I was thinking a plain good ol' C++98 SFINAE construction via enable_if
and the like, but other SO answers (like this one) make me think that MSVC 2013 may miscompile that too, so the result becomes unacceptable again.
Upvotes: 3
Views: 155
Reputation: 11181
I do not think you need expression SFINAE for this, something along these lines should work.
template<typename T>
typename std::hash<T>::result_type qHash(const T &t)
{
return std::hash<T>()(t);
}
Or pretty much any approach that does SFINAE on hash::result_type
. Unfortunately for you, hash::result_type
is deprecated in C++17, but you can still #ifdef
this code for MSVC 2013.
Upvotes: 2