Vector sortieren
-
knivil schrieb:
Functor ... eine Klasse "Comparator"
Es reicht auch eine einfache Funktion.
Ja klar, aber
Fischkopf2009 schrieb:
Und meine 2 Frage ich würde der Sortier funktion einen Parameter übergegebn, der angibt wonach sortiert werden soll.
Und das geht nunmal mit einer freien Funktion schlecht (außer man fängt mit globalen Sortier-Indikatoren an...).
-
l'abra d'or schrieb:
Und das geht nunmal mit einer freien Funktion schlecht (außer man fängt mit globalen Sortier-Indikatoren an...).
Man benutzt dann z.B. boost.bind
-
Der Parameter fuer die Sortierroutine ist die Vergleichsfunktion. Mehr braucht man fuer gewoehnlich nicht. Hier ein Tutorial, das ich dazu mal geschrieben habe: Sortieren in C++ für Fortgeschrittene. Dort sind alle Moeglichkeiten an Hand von sinnvollen Beispielen beschrieben (ohne boost).
-
evilissimo schrieb:
l'abra d'or schrieb:
Und das geht nunmal mit einer freien Funktion schlecht (außer man fängt mit globalen Sortier-Indikatoren an...).
Man benutzt dann z.B. boost.bind
Und hat wieder ein Funktionsobjekt
Ob ich nu eine freie Funktion habe und die bei jedem Aufruf von sort und an anderen Stellen wo ich sie brauche mit einem länglichen boost::bind verziere, oder gleich ein struct mache und mit wenig mehr Tip-Aufwand das binden gleich selbst übernehme, ein großer Unterschied ist da nicht, mal abgesehen davon dass ich den Typ des Comparators kenne und z.B. bei std::maps mit angeben kann - oder weiß jemand auswendig, was der exakte Typ von boost::bind(myFunc,5) ist?
-
pumuckl schrieb:
evilissimo schrieb:
l'abra d'or schrieb:
Und das geht nunmal mit einer freien Funktion schlecht (außer man fängt mit globalen Sortier-Indikatoren an...).
Man benutzt dann z.B. boost.bind
Und hat wieder ein Funktionsobjekt
Ob ich nu eine freie Funktion habe und die bei jedem Aufruf von sort und an anderen Stellen wo ich sie brauche mit einem länglichen boost::bind verziere, oder gleich ein struct mache und mit wenig mehr Tip-Aufwand das binden gleich selbst übernehme, ein großer Unterschied ist da nicht, mal abgesehen davon dass ich den Typ des Comparators kenne und z.B. bei std::maps mit angeben kann - oder weiß jemand auswendig, was der exakte Typ von boost::bind(myFunc,5) ist?Der typ der von boost bind zurück gegeben wird tut gar nichts zur sache. std::sort ist das doch egal was für ein typ das ist, dafür ist es ein template.
Wichtig zuwissen ist das man das zum beispiel boost::function zuweisen kann. Je nach signatur.Deine Argumentation das man dann ein funktionsobjekt hat macht jetzt nicht wirklich Sinn. Und das man dann mit etwas mehr aufwand das selber machen kann zeigt das du schein bar keine Ahnung hast was boost::bind eigentlich tut und wie man das verwendet.
Nur mal so als beispiel:
std::sort(employees.begin(), employees.end(), boost::bind( employee_sort_func, _1, _2, sort_by_name_tag ) ); std::sort(employees.begin(), employees.end(), boost::bind( employee_sort_func, _1, _2, sort_by_age_tag ) ); std::sort(employees.begin(), employees.end(), boost::bind( employee_sort_func, _1, _2, sort_by_salary_tag ) );
Dazu brauch ich ja wohl nichts mehr sagen oder
Edit: Ach ja und wenn dir der boost::bind aufruf zu umständlich sein sollte weil du ganz ganz viele kriterien hast und du sehr viele plätze hast an denen du das aufrufst, kannst du dir das auch noch mal abkürzen:
void sort_employees( std::vector< employee > & v, employee_sort_tag tag ) { std::sort(v.begin(), V.end(), boost::bind( employee_sort_func, _1, _2, tag ) ); } sort_employees( employees, sort_by_name_tag ); sort_employees( employees, sort_by_age_tag ); sort_employees( employees, sort_by_salary_tag );
Die gegen die freie Funktion würde nichts sprechen. Natürlich kannst du dir das auch in ein funktions objekt selbst wrappen, aber dann hättest du das von anfang an gemacht.
Das mit dem boost.bind Beispiel wurde auch nur von mir genannt da l'abra d'or meinte man könne das schlecht mit freien funktionen machen.
-
evilissimo schrieb:
Nur mal so als beispiel:
std::sort(employees.begin(), employees.end(), boost::bind( employee_sort_func, _1, _2, sort_by_name_tag ) ); std::sort(employees.begin(), employees.end(), boost::bind( employee_sort_func, _1, _2, sort_by_age_tag ) ); std::sort(employees.begin(), employees.end(), boost::bind( employee_sort_func, _1, _2, sort_by_salary_tag ) );
struct EmployeeComp { EmployeeComp(Tag t) : tag(t) {} bool operator()(Employee const& lhs, Employee const& rhs); Tag tag; }; std::sort(employees.begin(), employees.end(), EmployeeComp(sort_by_name_tag) ); std::sort(employees.begin(), employees.end(), EmployeeComp(sort_by_age_tag) ); std::sort(employees.begin(), employees.end(), EmployeeComp(sort_by_salary_tag) );
Kein großer Unterschied im Aufwand, oder? Genauer gesagt 6 Zeilen, davon eine Leerzeile und zweimal nur Klammern - abzüglich dem länglichen boost::bin-rattenschwanzz bei jedem Aufruf.
[quote="evilissimo"]Der typ der von boost bind zurück gegeben wird tut gar nichts zur sache. std::sort ist das doch egal was für ein typ das ist, dafür ist es ein template. [quote] Ich hab auch nicht behauptet, dass man für sort den Typ wissen muss. Für std::map mit entsprechendem Comparator braucht mans eben schon, und den Bonus kriegt man eben wenns manuell gemacht wird.
Und das man dann mit etwas mehr aufwand das selber machen kann zeigt das du schein bar keine Ahnung hast was boost::bind eigentlich tut und wie man das verwendet.
Ich denk schon dass ich ne recht passable Ahnung hab was boost::bin macht und wie mans verwendet - ich wollte nur aufzeigen dass man je nach Situation entscheiden sollte und nicht immer pauschal auf boost::bind zurückfallen sollte nur weil mans zur Verfügung hat.
Das mit dem boost.bind Beispiel wurde auch nur von mir genannt da l'abra d'or meinte man könne das schlecht mit freien funktionen machen.
Okay, dann haben wir wohl aneinander vorbeigeschrieben und/oder -gedacht. Kleines Missverständnis am Rande
-
Würde bind nicht verwenden weil es a) scheisse zu lesen ist, b) beschissen zu erweitern ist, c) eine Drittbibliothek ist (Pest).
-
Fellhuhn schrieb:
Würde bind nicht verwenden weil es a) scheisse zu lesen ist, b) beschissen zu erweitern ist, c) eine Drittbibliothek ist (Pest).
a) Ja.
b) Kommt drauf an, kann bein Selbstgestricktem genauso der Fall sein
c) Gibts einen Grund für diesen dogmatischen Ansatz kontra eine Drittbibliothek, (vor allem wenn man sie eh ständig verwendet)?
-
Zu c) wenn man sie gar nicht verwendet gibt es keinen Grund sie wegen so etwas reinzulinken.
-
Fellhuhn schrieb:
Zu c) wenn man sie gar nicht verwendet gibt es keinen Grund sie wegen so etwas reinzulinken.
reinlinken ist da ein wenig übertrieben, denn Boost besteht grösstenteils aus Header- Only Libraries.