std::set
-
Ich habe ein std::set das Objekte einer Klasse verwaltet. Der operator < ist über ein Attribut der Klasse definiert. Kann ich in dem std::set jetzt nach einem Objekt suchen, ohne eine Instanz der Klasse zu erstellen? Also angenommen dieses Attribut ist ein string, und ich möchte das Objekt suchen, das diesen string als Attribut hat.
-
Doof, gelle? Das geht dann nur über
std::find_if...
-
Du iterierst über alle Elemente des sets und guckst mittels einer passenden Funktion nach, ob das Element zu deinem Kriterium passt. Da dein Kriterium ja anscheinend nicht das Ordnungskriterium des sets ist, haben die beiden überhaupt nichts miteinander zu tun. Oder man kann diese Handsuche mit dem genannten find_if abkürzen, welches genau das oben beschriebene tut. Aber jetzt weißt du wenigstens, was da passiert.
-
SeppJ schrieb:
Da dein Kriterium ja anscheinend nicht das Ordnungskriterium des sets ist
Doch doch, ist es. Daher ja die Frage.
-
unreg schrieb:
SeppJ schrieb:
Da dein Kriterium ja anscheinend nicht das Ordnungskriterium des sets ist
Doch doch, ist es. Daher ja die Frage.
Ne, ist es nicht. Wenn Dein Elementtyp z.B.
Aist unduundvObjekte vom TypA, dann ist aus Sicht des setsu < vdas Ordnungsmerkmal. Es werden also Objekte vom TypAin Relation gesetzt. Dass intern ein String für denoperator<benutzt wird, kannstd::setnicht wissen. Das kann nur A-Objekte miteinander vergleichen.
-
Soweit war ich irgendwie auch schon..

Die Frage war, ob es trotzdem eine Möglichkeit gibt die schnelle Suche des set auszunutzen, undzwar möglichst elegant mit Standardmitteln.
-
unreg schrieb:
Soweit war ich irgendwie auch schon..

Die Frage war, ob es trotzdem eine Möglichkeit gibt die schnelle Suche des set auszunutzen, undzwar möglichst elegant mit Standardmitteln.Wieso fragst Du noch mal? Das wurde schon zwei mal beantwortet.
-
Das klingt fast so, als würdest du eine std::map wollen...
-
daddy_felix schrieb:
Das klingt fast so, als würdest du eine std::map wollen...
Das ist auch so, nur gehört der Key dem gemappten Objekt. Vielleicht könnte man eine Referenz benutzen, aber das Objekt kann ja im Speicher verschoben werden, insofern halte ich das für keine gute Idee.
Mich wundert auch etwas, dass dieses Problem noch nie jemand gehabt zu haben scheint.
-
achso, dieser key ändert sich - dann geht eine map natürlich nicht.
Alle, die dieses Problem bisher gehabt haben, werden std::find_if verwendet haben (oder das Verhalten von find_if nachprogrammiert). Wieso hast du denn so ein Problem mit dieser Lösung?
-
Weil es den Sinn des set (die schnelle Suche) kaputt macht.
-
Es *kann* keine schnelle Suche geben, wenn sich der entscheidende Key ändert. hast du mal geprüft, ob sich das "langsame" find_if überhaupt auf die Performance auswirkt?
-
Stopf alles in einen vector. Dazu dann noch eine jeweils map Ordnung nach Kriterium A auf Vectorindizes und eine map nach Kriterium B auf Indizes. Dann kannst du flott auf Daten nach unterschiedlicher Ordnung zugreifen. Alles schön in eine Supercontainerklasse gepackt.
Gibt's glaube ich auch schon fertig von Boost.
-
SeppJ schrieb:
Stopf alles in einen vector. Dazu dann noch eine jeweils map Ordnung nach Kriterium A auf Vectorindizes und eine map nach Kriterium B auf Indizes. Dann kannst du flott auf Daten nach unterschiedlicher Ordnung zugreifen. Alles schön in eine Supercontainerklasse gepackt.
das klingt ja an sich gut, allerdings muss er dann darauf achten, die Map zu aktualisieren, wenn sich der Key eines Elementes ändert... oder habe ich da jetzt einen Denkfehler?
-
Kein Denkfehler. Deswegen sprach SeppJja auch davon alles in eine Verwaltungsklasse zu stopfen. Duie übernimmt dann die Synchronisation.
-
und woher weiß die Verwaltungsklasse, dass sich in irgendeinem Objekt eine Membervariable geändert hat? Dazu müsste ja entweder das Objekt ein Signal aussenden oder die Verwaltungsklasse permanent die Member abfragen - und diese Member müssten dann auch öffentlich verfügbar sein.
-
Nein, deine Membervariablen machst du natürlich private. Nur die Verwaltungsklasse selbst bekommt die Rechte da was zu ändern. Du musst halt alle nötigen Zugriffsfunktionen implementieren.
-
Wenn es sich dabei um ein eigenes Objekt handelt, ok. Wenn man Objekte aus einer Library verwalten will, geht das schon nicht mehr. Und mir ist immer noch nicht klar, wie die Synchronisation laufen soll, wenn da Objekt keine Signale bei Änderungen des Wertes aussendet. Geht das auch anders als mit permanentem Polling? Was, wenn die Klasse nicht Thread-sicher ist?