While implementing a comparator operator inside a custom class for std::map
, I came across this question and couldn't see anywhere being asked.
Apart from the above question, also interested to know in brief, how operator<
would work for std::map
.
Origin of the question:
struct Address {
long m_IPv4Address;
bool isTCP;
bool operator< (const Address&) const; // trouble
};
std::map<K,D>
needs to be able to sort. By default is uses std::less<K>
, which for non-pointers uses <
1.
Using the rule that you demand the least you can from your users, it synthesizes "equivalence" from <
when it needs it (!(a<b) && !(b<a)
means a
and b
are equivalent, ie, neither is less than the other).
This makes it easier to write classes to use as key components for a map
, which seems like a good idea.
There are std
containers that use ==
such as std::unordered_map
, which uses std::hash
and ==
. Again, they are designed so that they require the least from their users -- you don't need full ordering for unordered_
containers, just equivalence and a good hash
.
As it happens, it is really easy to write a <
if you have access to <tuple>
.
struct Address {
long m_IPv4Address;
bool isTCP;
bool operator< (const Address& o) const {
return
std::tie( m_IPv4Address, isTCP )
< std::tie( o.m_IPv4Address, o.isTCP );
}
};
which uses std::tie
defined in <tuple>
to generate a proper <
for you. std::tie
takes a bunch of data, and generates a tuple
of references, which has a good <
already defined.
1 For pointers, it uses some comparison that is compatible with <
where <
behaviour is specified, and behaves well when <
does not. This only really matters on segmented memory model and other obscure architectures.
Because std::map
is a sorted associative container, it's keys need ordering.
An ==
operator would not allow to order multiple keys
You might be looking for std::unordered_map
, which work has a hashtable. You can specify your own hash and equality operator functions :
explicit unordered_map( size_type bucket_count,
const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual(),
const Allocator& alloc = Allocator() );
With <
you can order elements. If a < b
then a
should be placed before b
in the collection.
You can also determine if two items are equivalent: if !(a < b) && !(b < a)
(if neither object is smaller than the other), then they're equivalent.
Those two capabilities are all std::map
requires. So it just expects its element type to provide an operator <
.
With ==
you could determine equality, but you wouldn't be able to order elements. So it wouldn't satisfy the requirements of std::map
.
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