Вы можете передать указатель функции, объект функции (или увеличить lambda), в std :: sort, чтобы определить строгий слабый порядок элементов контейнера, который вы хотите отсортировать.Цепочка предикатов упорядочения (например, для std :: sort)
Однако иногда (достаточно, чтобы я ударил это несколько раз), вы хотите иметь возможность связывать «примитивные» сравнения.
Тривиальный пример: если бы вы сортировали коллекцию объектов, представляющих контактные данные. Иногда вам нужно сортировать по
last name, first name, area code. Другое время
first name, last name- еще раз
age, first name, area code... и т. Д.
Теперь вы можете, конечно, написать дополнительный объект функции для каждого случая, но это нарушает принцип DRY - особенно если каждое сравнение менее тривиально.
Похоже, что вы должны иметь возможность написать иерархию функций сравнения - низкоуровневые выполняют одиночные, примитивные, сопоставления (например, имя первого имени <), затем более высокие уровни называют нижние уровни подряд (возможно, с цепью & &, чтобы использовать оценку короткого замыкания) для создания составных функций.
Проблема с этим подходом заключается в том, что std :: sort принимает двоичный предикат - предикат может возвращать только bool. Поэтому, если вы их составляете, вы не можете сказать, означает ли «ложь» равенство или больше. Вы можете заставить предикаты нижнего уровня возвращать int с тремя состояниями - но тогда вам придется обернуть их в предикаты более высокого уровня, прежде чем их можно будет использовать с помощью std :: sort самостоятельно.
В целом, это не непреодолимые проблемы. Это кажется сложнее, чем должно быть - и, конечно же, приглашает реализацию вспомогательной библиотеки.
Таким образом, знает ли кто-нибудь о существовании ранее существовавшей библиотеки (особенно если это библиотека std или boost), которая может помочь здесь - иметь какие-либо другие мысли по этому вопросу?
[Update]
Как уже отмечался в некоторых комментариях - я пошел вперед и написал свою собственную реализацию класса справиться с этим. Он довольно минимален и, вероятно, имеет некоторые проблемы с ним в целом. но на этой основе, для тех, кто заинтересован, класс здесь:
И некоторые вспомогательные функции (чтобы избежать необходимости указывать шаблон арг) здесь:
Проблема с этой реализацией заключается в том, что ваши функции сравнения низкого уровня возвращают bools. Вы хотите только привязать следующее сравнение, если текущий тест сравнивается * равно *. – philsquared 2008-11-08 19:05:54
См. Мой собственный удар по этому вопросу, в котором я разместил ссылку в своем ответе на siukurnin, выше. Теперь я могу сделать: std :: sort (c.begin(), c.end(), MakeCompareChain (f1, f2, f3)); – philsquared 2008-11-08 19:07:05
Нет, это действительно работает - нам просто нужно сделать два сравнения (a == b то же самое, что и не (a 2008-11-08 19:24:55