Prädikate-Objekte für sortierte Container
-
Ich hab oft Klassen, deren Objekte ich nach dem Wert irgeneiner get-Funktion sortieren will.
Also z.B. die Klasse Mensch, die hat ne Methode getAlter() und ich möchte das ganze jetzt nach Alter sortieren.
Normalerweise schreib ich mir dann eine Klasse, die ich als Prädikat bei der Sortierfunktion oder auch als Komperator in nem sortierten Container angeben kann.
alse
listMenschen.sort( ByAlter()); std::set< Menschen, ByAlter> setMenschen;
Jetzt möcht ich mir die Arbeit sparen dauernd irgendwelche eigentlich einfachen Prädikat-Klassen schreiben zu müssen. Deswegen wollt ich mir eine Template-Prädikat-Klasse schreiben, der ich sage von welchem Typ die zu sortierende Klasse ist, welche Funktion aufgerufen werden soll und auch noch ein Prädikat zum Vergleich des Ergebnisses der Funktion.
Soweit so gut:
struct Foo { int bar()const; }; template < typename Tclass, typename Tcomp_val, typename Tpredicate=std::less<Tcomp_val> > class ByAnyThing :public std::binary_function< Tclass, Tclass, bool> { public: typedef Tcomp_val (Tclass::*get_fun_type)()const; get_fun_type get_fun_; ByAnyThing( get_fun_type get_fun) :get_fun_( get_fun) { } bool operator()( const Tclass& c1, const Tclass& c2) { return Tpredicate()( (c1.*get_fun_)(), (c2.*get_fun_)()); } }; //Anwendungsbeispiel void doSomething() { ByAnyThing< Foo, int> byFooBar( Foo::bar); std::list< Foo > lst; lst.sort( byFooBar); //wunderbar }
Das ist auch wunderbar, nur möchte ich das ganze jetzt auch noch für sortierte Container verwenden können. Und hier scheitere ich:
std::set< Foo, byFooBar> setOfFoos; //Fehler
Das liefert nen Fehler, weil ich natürlich kein Objekt als Template-Parameter angeben kann.
Das Problem ist aber, ich muss ein Objekt meiner ByAnyThing-Klasse machen, sonst kann ich ihr ja nicht sagen, welche Memberfunktion es aufrufen soll.
D.h. ich muss irgendwie das Member-Funktionsobjekt als Template-Parameter übergeben, weiß aber nicht wie?Der einzige Weg, der mir einfallen würde, ist, irgendwie mit Textersetzung und Makros zu arbeiten. Das gefällt mir aber natürlich garnicht
-
Hallo,
was spricht denn gegen?std::set<Foo, ByAnyThing<Foo, int> > s((ByAnyThing<Foo, int>(&Foo::bar)));
oder für Compiler die mit dem Parsen von Deklarationen probleme haben:
ByAnyThing<Foo, int> b(&Foo::bar); std::set<Foo, ByAnyThing<Foo, int> > s(b);
-
Das geht?
Mit meinem Code?
Ich bin genialer als ich dachteBesten Dank Dir!