To support user-defined key types in std::unordered_set<Key>
and std::unordered_map<Key, Value>
one has to provide operator==(Key, Key)
and a hash functor:
struct X { int id; /* ... */ }; bool operator==(X a, X b) { return a.id == b.id; } struct MyHash { size_t operator()(const X& x) const { return std::hash<int>()(x.id); } }; std::unordered_set<X, MyHash> s;
It would be more convenient to write just std::unordered_set<X>
with a default hash for type X
, like for types coming along with the compiler and library. After consulting
include\c++\4.7.0\bits\functional_hash.h
include\xfunctional
it seems possible to specialize std::hash<X>::operator()
:
namespace std { // argh! template <> inline size_t hash<X>::operator()(const X& x) const { return hash<int>()(x.id); } // works for MS VC10, but not for g++ // or // hash<X>::operator()(X x) const { return hash<int>()(x.id); } // works for g++ 4.7, but not for VC10 }
Given compiler support for C++11 is yet experimental---I did not try Clang---, these are my questions:
Is it legal to add such a specialization to namespace std
? I have mixed feelings about that.
Which of the std::hash<X>::operator()
versions, if any, is compliant with C++11 standard?
Is there a portable way to do it?
The unordered_map::hash_function() is a built in function in C++ STL which is used to get the hash function. This hash function is a unary function which takes a single argument only and returns a unique value of type size_t based on it.
using c++11, you can: #include <string> #include <unordered_map> std::size_t h1 = std::hash<std::string>{}("MyString"); std::size_t h2 = std::hash<double>{}(3.14159);
std::hash class in C++ STL It is used to get the hash value of the argument that is being passed to it. If the argument doesn't change, the value doesn't change either. Member functions: This Hash class only has one member function: operator(): It returns hashed value for given argument.
Working of the hash function in C++ with examples In C++, the hash function is a function where a key is pointing to a value which is an address; when this function is called, which uses the combination of letters and numbers in the hash table, which can be used for the arrangement of data.
You are expressly allowed and encouraged to add specializations to namespace std
*. The correct (and basically only) way to add a hash function is this:
namespace std { template <> struct hash<Foo> { size_t operator()(const Foo & x) const { /* your code here, e.g. "return hash<int>()(x.value);" */ } }; }
(Other popular specializations that you might consider supporting are std::less
, std::equal_to
and std::swap
.)
*) as long as one of the involved types is user-defined, I suppose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With