set aus struct - wie sortiert man nach einem structelement?
-
Es existiert ein set aus structs:
struct SetElem{ float Elem1; int Elem2; int Elem3; } std::set< SetElem > MySet;Wenn das set jetzt gefüllt wird (Myset.insert(...)), wie kann ich das Set nach einem der drei Elemente ordnen lassen?
Ideen wären fett!
ANGS_Pino
-
du musst dir eine funktions chreiben die diese structs sortieren kann
und die übergibts du an die sort funktion (ist set nicht das was automatisch sortiert? wenn jad ann musst du die funktion an das set übergeben)
-
Bei einem std::set kannst Du im 2. Templateparameter ein Vergleichsobjekt angeben, nach dem das set dann sortiert wird.
Das Vergleichsobjekt muß als Rückgabetyp einen bool liefern und 2 Argumente des zu vergleichenden Objektes akzeptieren.
Der Aufbau eines solchen Vergleichsobjektes (auch als Prädikat,Funktionsobjekt oder Functor bezeichnet) sieht im allgemeinen so aus:
class meinVergleich: public std::binary_function<meinTyp, meinTyp, bool> { bool operator() (const meinTyp& left, const meinTyp& right) const; }; bool meinVergleich::operator() (const meinTyp& left, const meinTyp& right) const { // hier findet der selbstdefinierte Vergleich statt };Das Ableiten von der Basisklasse 'binary_function' ist nicht unbedingt notwendig. In dieser Basisklasse werden den Datentypen der Argumente und Rückgabewerte standardisierte Namen gegeben, was später die Verwendung von Bindern ermöglicht. Die Klasse 'binary_function' ist in der Header-Datei 'functional' definiert.
die Deklaration des Set erfolgt dann folgendermaßen:
std::set<meinTyp, meinVergleich> meinSet
-
Du kannst auch eine Funktion als Prädikat nutzen. Kürzlich gab es zu diesem Thema einen Thread, siehe hier.
-
Man könnte auch einfach operator< für die struct überladen.
-
kleines Beispiel wie man die Vergleiche mittels struct-member generisch implementieren kann:
template <class T, class M, class Compare = std::less<M> > struct MemCompare { typedef typename M T::*MemPtr; MemCompare(MemPtr const memPtr, Compare cmp = Compare()) : comp(cmp), mem(memPtr) {} bool operator()(T const& lhs, T const& rhs) { return comp(lhs.*mem, rhs.*mem); } private: Compare comp; MemPtr mem; }; template <class T, class M, class Compare> MemCompare<T,M,Compare> memCompare(M T::* memptr, Compare cmp) { return MemCompare<T,M,Compare>(memptr, cmp); } template <class T, class M> MemCompare<T,M> memCompare(M T::* memptr) { return MemCompare<T,M>(memptr); } //Benutzungsbeispiel: struct A { A(int i) : t(i) {} public: int t; float u; char v; }; int main() { std::set<A, MemCompare<A,int> > mySet(memCompare(&A::t)); mySet.insert(A(5)); mySet.insert(A(1)); mySet.insert(A(22)); for (std::set<A, MemCompare<A,int> >::iterator it = mySet.begin(); it != mySet.end(); ++it) std::cout << it->t << " "; std::cout << std::endl; }(Vermutlich etwas Overkill für die Situation, man kanns aber immer wieder mal gebrauchen)
Braunstein: Operator< für die structs zu überladen ist nur dann sinnvoll wenn das dann eine verständliche Ordnungsrelation ergibt. Den Operator zu überladen nur damit std::set automatisch einen Comparator hat ist nicht der richtige Weg (siehe den Artikel zur Operatprüberladung)
-
Wenn es keine verständliche Ordnungsrelation gibt ist, meiner Meinung nach, auch eine Einordnung in ein set nicht sinnvoll, da die Existenz einer solchen hier erforderlich ist.
-
Braunstein schrieb:
Wenn es keine verständliche Ordnungsrelation gibt ist, meiner Meinung nach, auch eine Einordnung in ein set nicht sinnvoll, da die Existenz einer solchen hier erforderlich ist.
Es gibt auch Fälle, wo man eine Sortierung haben möchte, aber
operator<dafür nicht intuitiv scheint.Einfaches Beispiel: Klasse, die nach mehreren Kriterien sortiert werden kann. Oder halt Klassen, bei denen man nur durch Raten auf die Bedeutung der Kleiner-Relation kommt (z.B. 2D-Vektoren).
-
Wenn mehrere mögliche Ordnungsrelationen bestehen, oder besser, verwendet werden sollen, macht eine Überladung des Operator< natürlich keinen Sinn mehr.
Wenn nicht, sehe ich es immernoch als sinnvoll an den zu überladen.
Ich schätze mal das ist Ansichtssache.