VC6 mit std::greater überfordert??
-
Hallo,
Das VC6 mit der STL und C++ nicht ganz harmoniert war mir ja schon klar - auch wenn mir bis eben die Negativerfahrungen fehlten. Kann man folgendes Phänomen auch dem VC in die Schuhe schieben?
struct SortByVisibleState : public greater<DrawingPrimitive*>//sorting by Visible state -> e.g. if not in the current Layer -> false { bool operator()( DrawingPrimitive* pFirstDrawPrim, DrawingPrimitive* pTestDrawPrim ) const { return pFirstDrawPrim->GetShowState() > pTestDrawPrim->GetShowState(); } }; m_lDrawingPrimitives.sort( SortByVisibleState() );
kompiliert unter beiden VC6 und VC7 fehlerfrei, macht aber nur unter VC7 was es soll -> nähmlich sortieren. Nach alter Manier hab ich den fehler erst mal bei mir gesucht und 'ne Stunde vergeigelt. Ist die Zeit gekommen das VS6 endgültig über Bord zu werfen?
-
Wenn m_lDingsbums eine std::list ist, dann liegt es wohl daran, dass die sort-Elementfunktion ein template ist und template-Elementfunktionen im VC6/7 ziemlich schlecht unterstützt werden. Ich bin mit dem VC6 damals jedenfalls genau daran gescheitert und habe am Ende selbst sortiert. Vielleicht hat HumeSikkins ja einen Workaround...
-
Hallo,
ich gehe mal davon aus, dass m_lDrawingPrimitives eine std::list ist.
Drei Dinge:
1. list::sort soll laut Standard ein Membertemplate sein, welches als ersten und einzigen Parameter ein binäres Prädikat erwartet.
Da die beim VC 6.0 verwendete Dinkumware-Lib bereits für den VC 4.0 verwendet wurde und dieser keine Membertemplates unterstützt, ist list::sort hier kein Membertemplate. Stattdessen erwartet sie eine Instanz von greater<T>.2. Sowohl die Membertemplate-Version, als auch die VC 6.0 greater<T>-Version erhält den Parameter by value.
Das erklärt das von dir festgestellte Verhalten.
Unterstützt deine STL-Lib die Membertemplateversion, dann wird der Templateparameter korrekt zu SortByVisibleState hergeleitet.Da dein Prädikat von greater<T> erbt, funktioniert der Aufruf auch beim VC 6.0.
Allerdings findet hier slicing statt. Dein SortByVisibleState kommt innerhalb der sort-Funktion also nicht als SortByVisibleState-Objekt sondern als reines greater<T> Objekt an.3. Ich sehe keinen Grund dafür, dass du von greater<T> erbst.
Die VC 6.0 kompatible Lösung für dein Problem liegt in der Spezialisierung von greater<T>.
Es gibt hier sicher viele Wege. Spontan fällt mir sowas ein:
struct Foo { int i_; double d_; Foo(int i, double d) : i_(i) , d_(d) {} }; bool SortFooByInt(const Foo& f1, const Foo& f2) { return f1.i_ > f2.i_; } bool SortFooByDouble(const Foo& f1, const Foo& f2) { return f1.d_ > f2.d_; } // Spezialisierung sind erlaubt. Selbst im Namespace std namespace std { template <> struct greater<Foo> { public: greater(bool (*cmp)(const Foo&, const Foo&)) : cmp_(cmp) {} bool operator()(const Foo& f1, const Foo& f2) { return cmp_(f1, f2); } private: bool (*cmp_)(const Foo&, const Foo&); }; } int main() { list<Foo> f; f.push_back(Foo(1, 2.0)); f.push_back(Foo(2, 1.0)); f.sort(greater<Foo>(&SortFooByInt)); f.sort(greater<Foo>(&SortFooByDouble)); }
-
Hume, das war wieder mal Klasse!!
Also sozusagen ein "Umleitung" über den Funktionspointer auf meine Vergleichsfunktion.
Giebt es irgendwo eine Sammlung solcher Stolpersteine von STL und VC ala "Known Problems using STL with VC"? - Ich meine natürlich außer dem Buch, was du unbedingt mal schreiben solltest
-
Giebt es irgendwo eine Sammlung solcher Stolpersteine von STL und VC ala "Known Problems using STL with VC"?
Ich habe bisher leider keine gefunden. Ebensowenig wie eine Zusammenstellung aller bekannten Template-Workarounds. Die boost-Leute haben das Wissen dazu, leider aber wohl nicht die Zeit.
Ich meine natürlich außer dem Buch, was du unbedingt mal schreiben solltest
Klar ich schreibe ein entsprechendes Buch. Erscheinungsdatum: Ende 2005. Nur doof, dass es den VC 6.0 dann wohl nur noch im Museum gibt
Im Ernst: Der VC 6.0 ist imo tot. Und sollte man doch noch darauf angewiesen sein und muss damit ernsthafte Anwendungen schreiben, dann sollte man auf jeden Fall eine andere STL-Implementation verwenden. Z.B. STLPort.