Możesz przekazać wskaźnik funkcji, obiekt funkcji (lub zwiększyć lambda) do std :: sort, aby zdefiniować ścisłe słabe porządkowanie elementów kontenera, które chcesz posortować.Łańcuchy predykatów porządkowania (np. Dla std :: sort)
Jednak czasami (na tyle, że uderzyłem to kilka razy), chcesz mieć możliwość łączenia "prymitywnych" porównań.
Trywialnym przykładem byłoby sortowanie kolekcji obiektów reprezentujących dane kontaktowe. Czasami chcesz sortować według
last name, first name, area code. Inne czasy:
first name, last name- jeszcze innym razem
age, first name, area code... itd.
Teraz z pewnością można napisać dodatkowy obiekt funkcji dla każdego przypadku, ale narusza to zasadę DRY - szczególnie, jeśli każde porównanie jest mniej trywialne.
Wygląda na to, że powinieneś być w stanie napisać hierarchię funkcji porównawczych - te o niskim poziomie wykonują pojedyncze, prymitywne, porównania (np. Imię < pierwsze imię), następnie wyższe poziomy wywołują kolejne niższego poziomu (prawdopodobnie w połączeniu z & &, aby skorzystać z oceny zwarcia) w celu wygenerowania funkcji złożonych.
Problem z tym podejściem polega na tym, że std :: sort przyjmuje predykat binarny - predykat może jedynie zwrócić wartość bool. Więc jeśli je komponujesz, nie możesz powiedzieć, czy "fałsz" oznacza równość lub więcej niż. Możesz sprawić, by predykaty na niższym poziomie zwracały int, z trzema stanami - ale wtedy musiałbyś zawijać te w wyższych predykatach poziomu, zanim mogłyby zostać użyte z std :: sort na własną rękę.
W sumie nie są to nieprzezwyciężone problemy. Wydaje się, że jest trudniejsze, niż powinno być - i na pewno zachęca do wdrożenia biblioteki pomocniczej.
W związku z tym, czy ktoś wie o istniejącej wcześniej bibliotece (szczególnie jeśli jest to biblioteka standardowa lub wspomagająca), która może w tym pomóc? Czy mają Państwo inne zdanie na ten temat?
[Aktualizacja]
Jak wspomniano w niektórych komentarzach - Poszedłem do przodu i napisany własną implementację klasy zarządzać tym. Jest to dość minimalne i prawdopodobnie ma pewne problemy z nim w ogóle. ale na tej podstawie dla każdego zainteresowanego, klasa jest tutaj:
a niektóre funkcje pomocnicze (aby uniknąć konieczności zdefiniowanych szablonów args) jest tutaj:
Problem z tą implementacją polega na tym, że funkcje porównania niskiego poziomu zwracają wartości. Chcesz połączyć się z następnym porównaniem, jeśli bieżący test porównuje * równy *. – philsquared
Zobacz moje własne ukłucie w tym, że zamieściłem link do mojej odpowiedzi na siukurnin, powyżej. Mogę teraz zrobić: std :: sort (c.begin(), c.end(), MakeCompareChain (f1, f2, f3)); – philsquared
Nie, to działa - wystarczy wykonać dwa porównania (a == b jest taki sam jak nie (a