Определяя <для алгоритма сортировки STL - перегрузка оператора, функтор или автономная функция?

У меня есть stl:: список, содержащий объекты класса Виджета. Они должны быть отсортированы по словам двух участников в классе Виджета.

Чтобы сортировка работала, меньше, компаратор, сравнивающий два объекта Виджета, должен быть определен. Кажется, существует несметное число способов сделать это. Из того, что я могу собраться, каждый может также:

a. Определите перегрузку оператора сравнения в классе:

bool Widget::operator< (const Widget &rhs) const

b. Определите автономную функцию, берущую два Виджета:

bool operator<(const Widget& lhs, const Widget& rhs);

И затем заставьте Виджет классифицировать друга его:

class Widget {
    // Various class definitions ...
    friend bool operator<(const Widget& lhs, const Widget& rhs);
};

c. Определите функтор и затем включайте его в качестве параметра при вызывании функции вида:

class Widget_Less :
public binary_function<Widget, Widget, bool> { 
    bool operator()(const Widget &lhs, const Widget& rhs) const;
};

Кто-либо знает, какой метод лучше? В особенности мне интересно знать, должен ли я сделать 1 или 2. Я искал книгу Эффективный STL Scott Meyer, но к сожалению это не имеет ничего для высказывания об этом.

Спасибо за Ваш ответ.

10
задан Andy 13 March 2010 в 00:39
поделиться

4 ответа

Если вы сравниваете два виджета только друг с другом, используйте член оператора <. Если вы сравниваете Widget с чем-то еще, определите глобальный operator < (версия с двумя параметрами, как вариант - друг класса Widget, но это отдельный вопрос.

Функтор вам действительно нужен, только если вы делаете что-то менее ортодоксальное. Выбирайте функтор, если сравнение "меньше, чем" не имеет смысла в контексте виджетов. В этом случае наличие оператора < может сбить с толку. Конечно, функторы по-прежнему должны обеспечивать упорядочивание, но то, что это упорядочивание, не означает, что это операция "меньше, чем". (Пример, сортировка штатов по численности населения, вероятно, лучше подходит для функтора, чем оператор <.

11
ответ дан 3 December 2019 в 22:36
поделиться

Для большинства целей a. и b. одинаковы. Поэтому главный вопрос - когда использовать a/b и когда использовать c.

Ответ: используйте a или b, если "меньше чем" имеет смысл для вашего объекта в однозначных терминах. Если ваш класс - число, используйте <.

Если "меньше чем" не имеет смысла в контексте вашего класса, то, пожалуйста, не перегружайте "operator<" для вашего класса. Это запутает пользователей. Вместо этого используйте c., и либо сделайте его вложенным классом, либо типизируйте его внутри вашего класса, чтобы вы могли написать его как Widget::Compare.

1
ответ дан 3 December 2019 в 22:36
поделиться

а. б. Оператор сравнения двух виджетов - вещь не интуитивная, как для меня. Теперь я не вижу, что он может делать. Кроме того, если эта функция не является интуитивно понятной, когда вам понадобится один новый оператор сравнения, что вы можете сделать в этом случае?

Я предпочитаю функтор.

2
ответ дан 3 December 2019 в 22:36
поделиться

Все они должны быть одинаковыми с точки зрения производительности, но между ними есть и другие различия:

  • Первые два избавляют вас от необходимости явно указывать компаратор, и может быть легко использован с другими операциями, возможно, плохо определенными, которые не позволяют явно указать компаратор.

  • Только функтор позволяет использовать дополнительные данные для сравнения. Например, если вы сравниваете int s, вы можете создать сравнение, которое сравнивает их расстояние от третьей точки P, которая будет членом экземпляра функтора.

  • Функторы обычно труднее читать (для тех, кто не знаком с C ++).

Обратите внимание, что вам не нужно наследовать binary_operator , чтобы он работал, хотя он дает вам несколько хороших typedef s.

1
ответ дан 3 December 2019 в 22:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: