0

If I had a class Cell, for example, which I want to sort according to the following function (x and y here being int member variables with accessors):

bool sortByCoordinates(const Cell& c1, const Cell& c2) {
    return c1.getX() < c2.getX() || (c1.getX() == c2.getX() && c1.getY() < c2.getY());
}

Where exactly is the best place to put this function so that I can use it with a functions such as std::sort?

In the examples they just have the method floating in the source file above where it is needed, but in practice I want to keep it associated with the Cell class. I know that I could override the operator< but there might be other sort methods by which I'd like to sort Cell, and I'm not a big fan of overriding operators for code clarity's sake anyhow.

At the moment I have it as a static method in my Cell.h file, so that I can call it in when sorting like so:

std::sort(cells.begin(), cells.end(), Cell::sortByCoordinates);

Is this the best practice for multiple (or even singular) custom sort functions, and is the header file the right place for them? If not, what is?

Quetzalcoatl
  • 3,037
  • 2
  • 18
  • 27
  • 1
    Note: you should implement that using `std::tie`. – chris Mar 15 '14 at 00:36
  • @chris Ah thanks, I'm still fairly new to C++, had no idea that existed. – Quetzalcoatl Mar 15 '14 at 00:38
  • Actually, since you're accessing the values through member functions instead of having actual variables, `std::forward_as_tuple` might work better. Of course if they're something like `int`, `make_tuple` would probably work just as well. – chris Mar 15 '14 at 00:40
  • @chris I can use either, in fact the accessors are only still in that method due to me moving it around my code from file to file while trying to decide on where best to put it. If it turns out the best place to put it is in the `Cell.h/Cell.cpp` then I can use the actual variables. – Quetzalcoatl Mar 15 '14 at 00:42

1 Answers1

1

Doing it the way you describe is reasonable. And defining the comparison function inline in the header itself is a good idea if you care about performance (rather than defining it in the .cpp file).

Personally I have a different preference than you. I would declare this reasonable default comparison function at namespace scope (i.e. right below the class), because as written it does not need privileged access to class members. And I would declare it as operator <. I don't think there is anything to be ashamed about in terms of making one function "special" when it seems to be a reasonable default ordering.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Thanks for the advice, I think I shall go for the `inline static` at namespace scope idea for now. I'll leave this question open for a while to see if anyone else has anything else to chip in - otherwise I'll mark you as the accepted answer. – Quetzalcoatl Mar 15 '14 at 01:21
  • You're welcome. At namespace scope you only need to say `inline` at the definition (not decl.) and do not need `static` at all. – John Zwinck Mar 15 '14 at 02:33