Почему оператор <необходимо перегружать при реализации очередей на основе классов в c ++? - PullRequest
3 голосов
/ 26 марта 2009

примечание, я не прошу ответов. Мне просто любопытно, почему все работает

Мне нужно реализовать очередь приоритетов для симулятора принтера для назначения класса. Посмотрев примеры в Интернете, я заметил, что оператор <перегружен, чтобы правильно расположить приоритетную очередь. </p>

рассматриваемый код: пример очереди приоритетов java2s

Почему оператор <должен быть перегружен? Где '<' вообще используется для сравнения? Меняет ли реализация перегрузки оператора способ работы очереди STL? </p>

Эта реализация мне не кажется интуитивно понятной: почему вместо этого оператор> не перегружен? Как узнать, что оператор <должен быть перегружен для корректной работы priority_queue? </p>

Ответы [ 5 ]

9 голосов
/ 26 марта 2009

Контейнеры STL по умолчанию используют оператор <для заказа содержимого, для тех контейнеров, которые заказывают содержимое. </p>

Вы можете переопределить это, передав функтор сравнения конструктору контейнера, который позволяет отделить сортировку / упорядочение от объекта контейнера.

Оператор> мог быть выбран, но его нужно было выбрать, и это был оператор <, который затем используется везде для согласованности. </p>

4 голосов
/ 26 марта 2009

Почему оператор <должен быть перегружен? </p>

Функциональный объект Compare в priority_queue<T, Sequence, Compare>:

Сравнение вызывает строгий слабый порядок, как определено в требованиях LessThan Comparable, к типу аргумента.

Меньше, чем сопоставимая документация :

Примечания

1 Только оператор <является основным; остальные операторы неравенства по сути являются синтаксическим сахаром. </p>

2 Антисимметрия - это теорема, а не аксиома: она вытекает из нерефлексивности и транзитивности.

[3] Из-за нерефлексивности и транзитивности оператор <всегда удовлетворяет определению частичного упорядочения. Определение строгого слабого порядка является более строгим, а определение полного порядка - еще более строгим. </p>

Где '<' вообще используется для сравнения? </p>

void push(const value_type& x), который вставляет значение в очередь.

Меняет ли реализация перегрузки оператора способ работы очереди STL?

Да, конечно. Если вы поменяете местами порядок элементов в сравнении, ваш порядок будет другим.

2 голосов
/ 26 марта 2009

priority_queue<T> использует std::less<T>, что, в свою очередь, требует, чтобы T() < T() было допустимым выражением. Может быть членом, может быть не членом, но выражение должно быть допустимым.

Однако std::less<T> может быть специализированным, поэтому ваше утверждение, что оператор <должен быть перегружен, немного вводит в заблуждение. </p>

1 голос
/ 26 марта 2009

К вашему сведению: std :: priority_queue может принять предикат сравнения.
оператор <используется просто как поведение по умолчанию. Это минимальное требование. </p>

почему оператор не перегружен вместо

Я думаю, по историческим причинам. В математике все примеры обычно описываются для <операции, и достаточно одного оператора для определения всех других операций (>, <=,> =, ==,! =).

Эта реализация не кажется интуитивно для меня вообще

Для меня этот интерфейс был ожидаемым. Я думаю, что это как привычка.

Реализует ли оператор перегрузка меняет способ очереди STL работает?

Нет, нет. Не STL очередь, только ваша очередь - для вашего типа, если ваш собственный компаратор не был определен.

1 голос
/ 26 марта 2009

Хорошо, основная причина в том, что очередь с приоритетами - это структура, в которой вставленные элементы возвращаются в порядке некоторой функции порядка. Вам нужен порядок, и очевидный способ справиться с ним - перегрузить оператор <. Вы можете иметь функцию по имени, но способность сказать, что <code>if( a < b), возможно, более читабельна, чем if(isLessThan(a,b)) или что-то в этом роде.

Вы не перегружаете operator>, потому что это не нужно; единственная операция, которая вам нужна в очереди с приоритетами - меньше чем. Это не значит, что вы не могли иметь его, но, поскольку у вас есть ==, вы можете реализовать его тривиально - или просто обратить вспять операнды.

...