Vergleichsprädikat im Konstruktor konkretisieren
-
Hallo Forum,
Mein Anliegen ist es eine std::set zu sortieren, indem ich im Konstruktor sozusagen "Sortieroptionen" übergebe. Hier ein kleines Testprogramm, um mein Problem besser beschreiben zu können:
#include <set> #include <iostream> using namespace std; // Operator << für std::set<T> überladen template <class T> ostream& operator << (ostream& os, const set<T>& data) { for (set<T>::const_iterator i = data.begin(); i != data.end(); i++) os << *i << ' '; return os << endl; } // Funktor (abgeleitet von less<T>), der zusätzliche Optionen per Konstruktor zulässt template <class T> struct opt_less : public less<T> { const bool rev; opt_less(bool reverse = false) : rev(reverse) {} bool operator() (const T& lhs, const T& rhs) const { if (!rev) return less<T>::operator() (lhs, rhs); else return less<T>::operator() (rhs, lhs); } }; int main() { // int-set mit Zahlen zwischen 1 und 9 füllen int ia[] = {4, 2, 7, 8, 1, 5, 9, 6, 3}; set<int> is(ia, ia + sizeof(ia)/sizeof(ia[0]), // Funktionsobjekt mit Option (Ableitung von less) opt_less<int>(true)); cout << is; system("pause"); }Eigentlich sollte hier
9 8 7 6 5 4 3 2 1ausgegeben werden. Allerdings wird immer nur
less<T>anstattopt_less<T>verwendet, und die Ausgabe ist immer1 2 3 4 5 6 7 8 9Weiß jemand, wie ich das bewerkstelligen kann?
P.S. Ich weiß, dass ich einfach
set<int, greater<int> >schreiben könnte, aberbool revist bei mir nur eine Beispieloption.
-
Vererbung ist hier eine schlechte Idee. Da als zweites Templateargument des
std::setnichts spezifiziert wurde, wird per Defaultstd::less<int>genommen. Da du dein eigenes Prädikat vonstd::less<int>erbst, wird eine implizite Konvertierung zur Basisklasse vorgenommen, was nicht mal einen Fehler erzeugt.Lösung: Gleich
[c]std::set<int, opt_less_aber_mit_besserem_namen<int> > set;verwenden und im Konstruktor das richtige Argument übergeben.