Каким требованиям должен удовлетворять оператор «меньше» для использования в std::sort?

«Каким требованиям должен удовлетворять оператор «меньше» для использования в std::sort?» — вопрос из категории STL, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для использования в std::sort оператор сравнения (по умолчанию operator<) должен моделировать строгий слабый порядок (strict weak ordering). Это означает, что для любых элементов a, b и c должны выполняться следующие условия:

  1. Антирефлексивность: !(a < a) — элемент не меньше себя самого.
  2. Асимметричность: если a < b, то !(b < a).
  3. Транзитивность: если a < b и b < c, то a < c.
  4. Транзитивность эквивалентности: если a и b несравнимы (!(a < b) && !(b < a)) и b и c несравнимы, то a и c также должны быть несравнимы.

Нарушение этих правил, например, использование оператора <=, приводит к неопределенному поведению (undefined behavior).

Пример корректного компаратора для сортировки структур:

struct Point {
    int x, y;
};

bool compareByX(const Point& a, const Point& b) {
    // Строгий слабый порядок по полю x
    return a.x < b.x;
}

int main() {
    std::vector<Point> points = {{2, 5}, {1, 3}, {2, 1}};
    std::sort(points.begin(), points.end(), compareByX);
    // Результат: {1,3}, {2,5}, {2,1}
}