views:

91

answers:

4

What is the correct operator< for the following class?

struct Person {
  int height;
  int width;
  friend bool operator<(const Person&, const Person&);
};

Thanks!

+1  A: 

My boilerplate way of doing it:

friend bool operator<(const Foo& l, const Foo& r) {
    return l.width < r.width? true
         : r.width < l.width? false
         : l.height < r.height;
}

But consider using a typedef of pair<int, int> instead, if you can.

This somewhat meaninglessly orders things using all available data. (Here things are ordered first by width, and then by height if widths are equal.) If you are only using the ordering to find identical elements, that's probably what you want.

Potatoswatter
+7  A: 

That's entirely up to you and how you would want people to naturally sort. If you want short people first, but skinny to come before tall if they are the same height:

friend bool operator<(const Person& a, const Person& b) {
    return a.height != b.height ? a.height < b.height : a.width < b.width;
}

If you want some measure of a person's surface area to determine ordering:

friend bool operator<(const Person& a, const Person& b) {
    return a.height * a.width < b.height * b.width;
}
Marcelo Cantos
The surface area option may need a fallback in case their surface areas are equal. But that's up to the OP.
Chris Lutz
+1 for sorting people by surface area. That makes me giggle.
Dennis Zickefoose
@Chris: perhaps, but of course two people with the same surface area might be considered equal.
Marcelo Cantos
+1  A: 

Depends on the way you want to arrange/sort instances of person. An example would be

 bool operator<(const Person& one, const Person& two) {
     return one.height < two.height ||(one.height == two.height && one.width <two.width);
 }

i.e. first look at height (arranging by shortest first) , if heights are same, look at width, arranging by narrower first.

Jasmeet
+1  A: 

In order to put a class in a set you also need to take care of operator==. With the data you have in the class Person I don't think you can define a good operator==. Or are you meaning that two Persons having the same width and height are the same? I will add some unique identifier that allows to define a complete order for Person.

If you have no more information, you can use lexicographic order as pointed on another answer.

But never use the area to order them, otherwise you will need to define equality depending on the area and then (4,5) == (5,4) to get a complete order. I suppose you don't want that. Note that if !((4,5) < (5,4)) and (4,5) != (5,4), we can deduce that (5,4) < (4,5), which is false too.

If you are not using the ordered nature of a set, you could think of using a unordered_set or a hash table. But in any case you will need to take care of operator==.

Vicente Botet Escriba
Good point, but if in this case there is no data being stored about the people other than their width and height, and making copies of person objects is allowed, then for these purposes, two people with the same width and height *are* the same, since they are indistinguishable from two copies of one person. Your point is that usually this isn't what you want, but it's not necessarily wrong as long as the OP understands what it implies.
Tyler McHenry
@Tyler You are right, but not any definition of operator< is a valid one. See my edit.
Vicente Botet Escriba