I need std::unordered_set
of pairs, whose first elements should be different.
Is it correct to hash only first element of pairs, as below?
using Pair = std::pair<int, int>;
struct Eq
{
bool operator() ( Pair const& lhs,
Pair const& rhs ) const
{
return (lhs.first == rhs.first);
}
};
struct Hash
{
std::size_t operator() ( Pair const &p ) const
{
return std::hash<int>()( p.first );
}
};
// No two pairs with same '.first'.
std::unordered_set<Pair, Hash, Eq> pairs;
for ( Pair const& p : ... )
{
pairs.insert(p);
}
In general, for unordered_set<T>
:
If equality functor for type T
does not use part (some data members) of T
, it makes sense not to use that part in hash<T>
either.
Is this right?
Yeap, should work fine. From the documentation to std::unordered_set::insert() (emphasis mine):
Inserts element(s) into the container, if the container doesn't already contain an element with an equivalent key.
You clearly provided a predicate that says elements should be treated equivalent when their first
fields match. And you specified a hash that makes sure equivalent elements end up in the same bucket. So this looks good to me.