If I have a class that I want to be able to sort (ie support a less-than concept), and it has several data items such that I need to do lexicographic ordering then I need something like this:
struct MyData {
string surname;
string forename;
bool operator<(const MyData& other) const {
return surname < other.surname || (surname==other.surname && forename < other.forename); }
};
This becomes pretty unmanageable for anything with more than 2 data members. Are there any simpler ways of achieving it? The data members may be any Comparable class.
Definition: Lexicographic order and comparison. Lexicographic ordering means dictionary like ordering on types that have several elements in some defined sequence. If the first element of a sequence A is less than the first element of a sequence B then A is lexicographically less than B .
With the lexicographic method, preferences are imposed by ordering the objective functions according to their importance or significance, rather than by assigning weights. After we arrange the objective functions by importance, the most important objective is solved first as a single-objective problem.
Lexicographical order is nothing but the dictionary order or preferably the order in which words appear in the dictonary. For example, let's take three strings, "short", "shorthand" and "small". In the dictionary, "short" comes before "shorthand" and "shorthand" comes before "small". This is lexicographical order.
With the advent of C++11 there's a new and concise way to achieve this using std::tie:
bool operator<(const MyData& other) const {
return std::tie(surname, forename) < std::tie(other.surname, other.forename);
}
tuple
is a good idea, but if you want to keep having names for your member variables, it might be good enough to restructure your comparison function like this:
struct MyData {
string surname;
string forename;
string var;
// ...
bool operator<(const MyData& other) const {
if (surname != other.surname) return surname < other.surname;
if (forename != other.forename) return forename < other.forename;
if (var != other.var) return var < other.var;
// ...
return false; //< They are equal
}
};
Depending on your taste, you might even want a macro like #define COMPARE(field) if (field != other.field) return field < other.field;
to reduce duplication. Then the function would just become a list of COMPARE
-invocations.
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