I would like to use a standard map with the following custom key:
struct ParserKey{
ParserKey(uint16_t compno,
uint8_t resno,
uint64_t precinctIndex) : compno_(compno),
resno_(resno),
precinctIndex_(precinctIndex)
{
}
uint16_t compno_;
uint8_t resno_;
uint64_t precinctIndex_;
};
There's no obvious way of ordering the keys, though. Can these keys be ordered, or do I need a different associative collection ?
CodePudding user response:
If you don't care about the specific order and just want to satisfy the requirements for sorting, a common and simple pattern is to use std::tie
with all of the class members of the compared instances, and compare those results instead.
std::tie
creates a std::tuple
of references to the members, and std::tuple
implements operator<
which compares its elements (the members of the object in this case) lexicographically.
In your case, using member operator<
:
bool operator<(const ParserKey & other) const
{
return std::tie(compno_, resno_, precinctIndex_) <
std::tie(other.compno_, other.resno_, other.precinctIndex_);
}
Live example https://godbolt.org/z/v433v54jz
CodePudding user response:
You can just impose any arbitrary total order on these integers in the same style as std::lexicographical_compare
does.
So, the lazy approach is:
// inside ParserKey ...
std::array<std::uint16_t,3> to_array() const {
return {compno_, resno_, precinctIndex_};
}
friend bool operator<(ParserKey const& lhs, ParserKey const& rhs) {
auto const l = lhs.to_array();
auto const r = rhs.to_array();
return std::lexicographical_compare(begin(l),end(l), begin(r), end(r));
}
But it carries the overhead of pressing your members into an iterable container. If you don't want that, you might have to reimplement a lexicographical compare yourself.
CodePudding user response:
In C 20 you can do this: (at class scope)
friend auto operator<=>(const ParserKey &, const ParserKey &) = default;
Don't forget to #include <compare>
.
This will give you all 6 relational operators: ==
, !=
, <
, <=
, >
, >=
, performing lexicographical comparison (same as in @FrançoisAndrieux's answer).