std::map mit eigenem Ordnungsvergleich
-
Wenn ich als Key-Typ bei der Map was nehme, was sich nicht mit '<' vergleichen lässt, muss ich ja eine Klasse angeben, mit der er vergleicht, richtig? Ich dachte jetzt, das geht dann so, aber anscheinend nicht...
Sieht vielleicht jemand den Fehler?#include <map> using std::map; using std::binary_function; class Item { int value; public: Item(int value) { this->value = value; } Item(Item& obj) { value = obj.getValue(); } int getValue() { return value; } }; class Less : public binary_function<Item*, Item*, bool> { public: Less() {} bool operator()(const Item*& a, const Item*& b) { return const_cast<Item*>(a)->getValue() < const_cast<Item*>(b)->getValue(); } }; int main() { map<Item*, int, Less> foo; foo[new Item(5)] = 5; return 0; }
-
DollyDuplex schrieb:
Ich dachte jetzt, das geht dann so, aber anscheinend nicht...
Ich hoffe es antwortet keiner mehr auf solche Fehlerbeschreibungen
-
DollyDuplex schrieb:
Sieht vielleicht jemand den Fehler?
die kristallkugel haben wir versetzt.
Wie man Fragen richtig stellt
-
foo[new Item(5)] = 5;

-
DollyDuplex schrieb:
Sieht vielleicht jemand den Fehler?
Ja. Dennoch wäre's nicht ungeschickt gewesen zumindest anzudeuten was denn "dann nicht so geht".
class Item { public: Item( int value ) : value(value) { } // kommt aufs selbe raus Item( Item& obj ) : value(obj.value) { } // class 'Item' is implicitly friends with itself int getValue() const { return value; } // const-correctness private: int value; }; // der Funktor muss nicht von binary_function abgeleitet sein, sollte aber wenn möglich halbwegs // sinnvoll benannt sein. struct ItemValueLess { //Less() {} // Konstruktor unnoetig // hier war dein Fehler: der Pointer muss const sein, nicht unbedingt das Item worauf er zeigt; // und "foo*&" ist nicht unbedingt billiger als schlicht zu kopieren. bool operator()( Item const* const a, Item const* const b) const { return a->getValue() < b->getValue(); // weg mit dem cast } }; int main() { map<Item*, int, ItemValueLess> foo; foo[new Item(5)] = 5; // wer raeumt das bloss wieder auf? warum nimmst du keine Objekte? return 0; }
-
ich denke irgendwie an
#include <map> using std::map; class Item { int value; public: Item(int value) { this->value = value; } Item(Item& obj) { value = obj.getValue(); } int getValue() { return value; } friend bool operator<(Item const& a,Item const& b){ return a.value<b.value; } }; struct PointeeLess{ template<typename A,typename B> bool operator()(A* a,B* b) { return *a<*b; } }; int main() { map<Item*, int, PointeeLess> foo; foo[new Item(5)] = 5; return 0; }
-
warum überhaupt ne item klasse ? es reicht doch wenn man die vergleichsfunktion für den asoziationstyp direkt angibt
-
r0nny schrieb:
warum überhaupt ne item klasse ? es reicht doch wenn man die vergleichsfunktion für den asoziationstyp direkt angibt
speed
-
templäd schrieb:
DollyDuplex schrieb:
Ich dachte jetzt, das geht dann so, aber anscheinend nicht...
Ich hoffe es antwortet keiner mehr auf solche Fehlerbeschreibungen
Oh, Verzeihung für das Einbringen einer Floskel ohne offensichtlichen Informationsgehalt. Was ich damit meine ist: Ich hab das ja nicht durch göttliche Eingebung zusammengeschustert, sondern versucht es nachzuschauen. Nur hat es als ich es (so dachte ich) so gemacht hab, wie es da stand, trotzdem nicht funktioniert.
camper schrieb:
DollyDuplex schrieb:
Sieht vielleicht jemand den Fehler?
die kristallkugel haben wir versetzt.
Wie man Fragen richtig stelltOK, interessant. Entschuldigt, wenn ich dumm Frage; ich bin wohl aus der Übung, weil ich mir die Lösungen meiner Probleme meistens selbst aus dem Allerwertesten leiere.
finix schrieb:
der Funktor muss nicht von binary_function abgeleitet sein
[...]
"foo*&" ist nicht unbedingt billiger als schlicht zu kopieren.Hmjaa, ich hab eben versucht, es so zu machen wie die in der Referenz (OK, das mit der binary_function hab ich von wo anders), die haben 'bool operator()(const T& x, const T& y)' und mein 'T' ist eben 'Item*'.
wer raeumt das bloss wieder auf?
Das Ganze ist ja nur das Problem aus dem Programm herausgezogen, sonst würde es wohl komplexer... In Wirklichkeit heissen die Sachen natürlich alle anders und die Objekte werden auch wieder gelöscht. :p
Alles in allem: Entschuldigt bitte die Unannehmlichkeiten und Danke für die Lösung!
PS: Es scheint keine Angabe für den Test auf Gleichheit zu geben, verstehe ich das richtig, dass er das über das 'kleiner' löst (x = y wenn weder x < y noch y < x)?
-
DollyDuplex schrieb:
Hmjaa, ich hab eben versucht, es so zu machen wie die in der Referenz (OK, das mit der binary_function hab ich von wo anders), die haben 'bool operator()(const T& x, const T& y)' und mein 'T' ist eben 'Item*'.
Eben. Der Funktor muss mit konstantem T aufrufbar sein, daher solltest du den Pointer kopieren oder per const-ref übergeben, sprich "Item * const", nicht "Item const *".
-
finix schrieb:
"Item * const", nicht "Item const *".
OMG, in diesem "Wo gehört das 'const' hin?"-Spiel war ich noch nie sonderlich gut. In meinem Code ist irgendwie so gut wie nix const...
