Funktionsaufruf aus einer Klasseninternen Struct?
-
Hallo
Aus einem Vector mit Kundennummern sollen diejenigen entfernt werden, die ein Product (Item) bereits haben. Das Predikat für remove_if bräuchte also 2 Argumente plus Zugriff auf die Map mit den Daten. Dazu wollte ich folgende Konstruktion machen:
typedef int ItemType; class Controler { public: ... void hasItem( int customer ) { return ( items[item].end() != find( items[item].begin(), items[item].end(), customer ) ); } struct hasNoItem { bool operator()( int value ) { return !( hasItem( value ) ); } }; void doOrder( int customer, ItemType item_ ) { item = item_; customers.erase( remove_if( customers.begin(), customers.end(), hasNoItem() ), customers.end() ); ... item = 0; } private: ItemType item; map<ItemType, vector<int> > items; vector<int> customers; };Das geht nun nicht, der Fehler ist:
error C2352: 'Controler::hasItem' :illegal call of non-static member function
Wenn ich die hasItem() static mache, dann kann ich aber nicht auf die Member item und items zugreifen. Wie kann ich das lösen, ev auch mit nem anderen Design?edit 1 + 2: Logikfehler (!!)
-
Ok, hab jetzt halt die Member item und items auch static gemacht. Spielt auch keine Rolle, weils eh nur eine Instanz der Klasse geben wird.
-
1310-Logik schrieb:
Ok, hab jetzt halt die Member item und items auch static gemacht. Spielt auch keine Rolle, weils eh nur eine Instanz der Klasse geben wird.
Also ehrlich gesagt: Dann würde ich das komplett OO-frei machen.

Mit statics sollte man aufpassen (auch z.B. beim Multithreading)....Mal ganz global: "Innere Objekte haben keinerlei Verbindung zu ihren äußeren"
(ganz anders als "nested classes" in java) .... aber dafür ist es kein Problem, dem Funktor eine Objektreferenz zu übergeben (const-correctness u.ä. habe ich mal außen vor gelassen):class Controler { ... struct hasNoItem { hasNoItem(Controler & c) : controler(c) {} bool operator()( int value ) { return !( controler.hasItem( value ) ); } Controler& controler; }; void doOrder( int customer, ItemType item_ ) { item = item_; customers.erase( remove_if( customers.begin(), customers.end(), hasNoItem(*this) ), customers.end() ); item = 0; } ... };Insgesamt finde ich die Programmierung aber zu verschachtelt (besonders die "Abkürzung via remove_if" mit "künstlichem KlassenAttribut item") ....
Aber must Du selbst wissen und ich kann nicht beurteilen, ob das wirklich zu vereinfachen wäre (man darf auf mehrere Klassen einrichten, um verschiedene Zusammenhänge abzubilden
...)Gruß,
Simon2.
-
Simon2 schrieb:
Insgesamt finde ich die Programmierung aber zu verschachtelt (besonders die "Abkürzung via remove_if" mit "künstlichem KlassenAttribut item") ....
Aber must Du selbst wissen und ich kann nicht beurteilen, ob das wirklich zu vereinfachen wäre (man darf auf mehrere Klassen einrichten, um verschiedene Zusammenhänge abzubilden
...)Danke mal für Deine Antwort.
Ich kann das auch nicht beurteilen, kA wie ich das einfacher lösen könnt. Ist mir auch zu verschachtelt, lieber wär mir nur ein Funktionsobjekt ohne Aufruf von hasItem(), oder wenns noch anders ginge, ausser zu Fuss.
Wie würdest Du es denn machen?
-
Wie wärs mit Boost?
#include <boost/bind.hpp> #include <iostream> #include <map> #include <vector> typedef int ItemType; class Controler { public: bool hasItem(int customer, ItemType item) { /* klammern bei return sind doof */ return items[item].end() != find(items[item].begin(), items[item].end(), customer); } void doOrder(/* warum das hier? int customer, */ ItemType item) { customors.erase( std::remove_if(customors.begin(), customors.end(), boost::bind(boost::mem_fn(&Controler::hasItem), this, _1, item)), customors.end() ); } private: std::map<ItemType, std::vector<int> > items; std::vector<int> customors; }; int main() { Controler foo; foo.doOrder(0); }Habs nur compiliert, nicht getestet auf Funktion. Bin mir gar nicht sicher ob ich verstanden hab was es tuen soll
