templates, functoren, virtual
-
hi,
ich habe ne klasse Sorter, von der verschiedene sortieralgorithmen ableiten und die abstrakte virtuelle funktion DoSort ueberschreiben um dort das sortierverfahren zu implementieren. zur zeit sortieren alle aufsteigend. um nun auch nach anders sortieren zu können (absteigend oder nach anderen kriterien) wollte ich die klasse um eine functor erweitern (siehe unten) den ich dann beim aufruf uebergebe und der den vergleich uebernimmt.
problem ist nun das virtual von DoSort. mein compiler mosert rum, das virtual und template (template <typename Functor> nicht zusammen funktionieren. aber ohne diese kann ich ja den functor nicht an die ableitende klasse uebergeben.
wie löse ich dieses problem am besten?
template <typename T> class Sorter { protected: // elemente vertauschen virtual void Swap(T *a, T *b); template <typename Functor > virtual void DoSort(T *Left, T *Right, Functor Compare) = 0; public: template <typename Functor > void Sort(T *Left, T *Right, Functor Compare); };// Shell-Sort template <typename T> class ShellSorter : public Sorter<T> { protected: // void DoSort(T *Left, T *Right); template <typename Functor> void DoSort(T *Left, T *Right, Functor Compare); };template <typename T> class Less { public: // Funktionsoperator bool operator () (const T &lhs, const T &rhs) const { return (lhs < rhs); } };p.s. gleich vorne weg nein ich will kein std::sort verwenden!

-
Das Problem dürfte sein, daß du eine "normale" Funktion durch ein Template überlädst. Ohne Garantie für die Richtigkeit:
template<typename T> class Sorter { protected: // elemente vertauschen virtual void Swap(T *a, T *b); template<typename Functor> virtual void DoSort(T *Left, T *Right, Functor Compare) = 0; public: template<typename Functor> void Sort(T *Left, T *Right, Functor Compare); };Wenn das nicht funktioniert, kannst du höchstens noch "typename Functor=Less<T>" als zweiten Parameter der Sorter-Klasse angeben.
-
sorry hab das beim copy/paste vergessen...
-
In dem Fall dürfte es wirklich ein Konflikt zwischen statischer und dynamischer Zuordnung sein. Templates sind von Natur aus statisch, d.h. sie müssen zur Compilezeit zugeordnet werden. Virtuelle Funktionen sind dynamisch und können erst zur Laufzeit richtig zugeordnet werden. Damit bleiben dir nur drei grundsätzliche Möglichkeiten:
a) du verzichtest auf die "Virtualität"
b) du verschiebst den "Functor"-Parameter auf Klassenebene (bin nicht sicher, ob das möglich ist):template<typename T,typename Functor=Less<T> struct sorter{...}c) du baust dir einen Vergleichsoperator, der (halb)dynamisch sein Verhalten ändern kann:
template<typename T> class compare{ const bool less; public: compare(bool n_less) : less(n_less) {} bool operator()(const T& lhs,const T& rhs) const { return less ? lhs<rhs : lhs>rhs; } } //... mySorter.Sort(start,end,compare<char>(true));//sortiere char's steigend mySorter.Sort(start,end,compare<char>(false));//sortiere char's fallend
-
okay, mit dem 2. parameter gehts jetzt, habe aber dann solche konstrukte beim aufruf...
template <typename T> class Greater { public: // Funktionsoperator bool operator () (const T &lhs, const T &rhs) const { return (lhs > rhs); } }; aiLibBasics::Greater<int> G; ShellSorter<int, Greater<int> > S; S.Sort(Liste + 0, Liste + LaengeListe - 1, G);ist das so gedacht oder stehe ich heute nur extrem aufm schlauch?
-
Sunday schrieb:
hi,
ich habe ne klasse Sorter, von der verschiedene sortieralgorithmen ableitenschlechte idee.
klassen, die keine attribute haben und nur eine methode, sind eigentlich funktionen. also mach auch funktionen.
die dann per funktor-wrapper in eine liste stecken, wird ein anderes (einfaches) problem.