Given a programmer defined POD struct
that will be stored in an unordered_map
, is there any particular advantage in defining:
namespace std {
template<>
struct equal_to<MyType> {
bool operator()(const MyType& lhs, const MyType& rhs) const {
...
}
};
}
over simply defining:
operator==(const MyType& lhs, const MyType& rhs)
(I'm already aware of the potential advantage of using an "inlineable" function object rather than a function pointer for the hashing function).
I would say operator==
has more uses than a specialization of equal_to<>
because people normally write a == b
, not equal_to<T>()(a, b)
. And the default equal_to<>
is implemented in terms of operator==
, not the other way around.
If you need to specialize std::equal_to
because it must behave differently from operator==
, then a better idea may be to implement a custom my_equal_to
predicate class, not related to std::equal_to
in order to follow the principle of least surprise.
Also, there is interface deficiency in std::equal_to<T>
because it accepts arguments of the same type. C++14 std::equal_to<void>
fixes the deficiency by accepting arguments of different types and forwarding them to operator==
.
operator==
, on the other hand, can have multiple overloads for different types (e.g. operator==(std::string const&, char const*)
).
Which means that in C++14 std::equal_to<void>
and overloaded operator==
work nicely together, see N3657 Adding heterogeneous comparison lookup to associative containers for more details.
I'm already aware of the potential advantage of using an "inlineable" function object rather than a function pointer for the hashing function
Function pointers do not apply here, default equal_to<>
uses operator==
directly, not through a pointer.
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