I have a struct that is just two ints that I want to store in std::set
, while also taking advantage of its sorting properties. For example
struct Item
{
int order;
int value;
};
So I wrote a comparator
struct ItemCmp
{
bool operator()( const Item& lhs, const Item& rhs ) const
{
return lhs.order < rhs.order || lhs.value < rhs.value;
}
};
The intent is that Item
should be sorted in the collection by ORDER first, and then by VALUE. If I put these Item
in a vector
and use std::sort
, seems to be working as expected.
I also implemented unit tests for the cases in https://en.cppreference.com/w/cpp/named_req/Compare
However now this test case is failing:
std::set<Item, ItemCmp> stuff;
stuff.insert( {1, 1} );
stuff.insert( {1, 1} );
CHECK( stuff.size() == 1 );
The size of the set
is 2, violating the contract of set
. Where am I going wrong?
based on @retired-ninja 's comment, the answer is to ensure the comparator does proper lexicographical comparison. One shortcut to this is to leverage std::tuple
's operators (see https://en.cppreference.com/w/cpp/utility/tuple/operator_cmp ) using this example:
return std::tie(lhs.order, lhs.value) < std::tie(rhs.order, rhs.value);