adresse einer virtuellen memberfunktion als template-parameter für einen member
-
Der BCC (5.9) erzeugt bei obigem Beispiel auch einen ICE, und auch hier funktioniert es, wenn man die Deklaration von blub z.B. nach main() verschiebt (also trifft campers Vermutung wohl zu). Auch campers Workaround wird übersetzt.
Was den Nutzen angeht: solche Konstrukte wie diesen boost::property-Entwurf habe ich früher auch manchmal gebaut, aber abgesehen davon, daß es schön aussieht, ist der Nutzen ohne Möglichkeiten wie Reflection doch recht beschränkt, und zudem erhöht es lediglich den Speicherbedarf der Klasse wegen des in dem Property-Objekts gespeicherten this-Zeigers. Oder übersehe ich da etwas?
-
Danke für die vielen aufschlussreichen Antworten, besonders an camper u. Checker&Murckser.
Tatsächlich läuft es ohne /Gm problemlos durch.
Genau so etwas hab ich gesucht
audacia schrieb:
...
Was den Nutzen angeht: solche Konstrukte wie diesen boost::property-Entwurf habe ich früher auch manchmal gebaut, aber abgesehen davon, daß es schön aussieht, ist der Nutzen ohne Möglichkeiten wie Reflection doch recht beschränkt, und zudem erhöht es lediglich den Speicherbedarf der Klasse wegen des in dem Property-Objekts gespeicherten this-Zeigers. Oder übersehe ich da etwas?Stimmt, man könnte zwar noch ein paar mehr Spielereien mit den properties anstellen, aber der Hauptnutzen ist dass es schöner aussieht.
Ich finde halt sowas wie:
car.Speed += 20;schon deutlich schöner als:
car.setSpeed(car.getSpeed() + 20);Das ist mir als Programmierer den überflüssigen this-Zeiger etc. wert.
Die Frage beim Klassendesign, die hierbei natürlich aufkommt ist, ob man die get/set-Funktionen dann private macht damit der Nutzer nur das Property benutzen kann oder ob man sie public lässt.
-
Verwirrenderweise gibt folgendes trotzdem deaktiviertem /Gm wieder einen Internen Kompilierfehler:
template<class T> struct wrapper { }; template<class T, void(T::*F)()> struct foo { }; struct bar { virtual void something() { } wrapper< foo<bar, &bar::something> > blub; }; int main() { return 0; }Es gilt wieder:
- Macht man something nicht-virtuell, geht es.
- Packt man blub außerhalb von bar, geht es ebenfalls.Ein typedef für foo<bar, &bar::something> löst das Problem leider nicht.
Wirklich komischer Compiler, dieser MSVC++.
Leider ist so etwas für die Benutzung von Boost.Property nötig.
-
Der Workaround über die Basisklasse funktioniert offenbar nicht:
struct bar_base { virtual void something() {} }; struct bar : bar_base { virtual void something() { } }; #include<iostream> int main() { std::cout << (&bar::something==&bar_base::something); // gibt 1 aus // int x[&bar::something==&bar_base::something]; // geht schief return 0; }Diese Konvertierung während des Compilierens erfolgt offenbar nicht richtig und ist ohnehin nicht konform. Die Benutzung einer nichtvirtuellen Funktion dürfte die beste Lösung sein, das ist standardkonform und m.E. sowieso guter Stil.
-
Ich wuerde trotzdem mal noch MS Bescheid sagen, damit die das fixen. Dafuer bezahlt man schliesslich denen auch das Geld. f'`8k
AutocogitoGruß, TGGC (making great games since 1992)
-
Pyr0kar schrieb:
Das ist mir als Programmierer den überflüssigen this-Zeiger etc. wert.
Auch den Laufzeitnachteil, der entsteht, weil die Funktion nicht inline generiert werden kann, da auf sie über einen Zeiger zugegriffen wird?
Eine eher unschöne, aber saubere Lösung dürfte übrigens folgendes sein:
template <class T, void (T::*F) (void)> struct foo {}; struct bar { virtual void func (void) { } private: void func_wrapper (void) { func (); } public: foo <bar, &bar::func_wrapper> blub; };
-
audacia schrieb:
Eine eher unschöne, aber saubere Lösung dürfte übrigens folgendes sein:
unschön, weil du public und private falsch gesetzt hast
virtuelle Funktionen sollten sowieso nicht public sein.
-
camper schrieb:
virtuelle Funktionen sollten sowieso nicht public sein.
??
-
audacia schrieb:
camper schrieb:
virtuelle Funktionen sollten sowieso nicht public sein.
??
schließ mich an
Wieso das denn? Ich hab die immer mit dem Sichtbarkeitsattribut versehen, was ich brauchte - auch public ...
-
*push*
-
camper schrieb:
virtuelle Funktionen sollten sowieso nicht public sein.
Das bezieht sich doch auf deinen Code, wo aber virtual-func() private ist. Aber camper sagt "sollten sowieso", als ob du sie public hättest. Gehe mal deswegen davon aus das es nur ein vertipper war

Private virtuals machen nämlich nicht gerade viel Sinn ...
-
KasF schrieb:
camper schrieb:
virtuelle Funktionen sollten sowieso nicht public sein.
Das bezieht sich doch auf deinen Code, wo aber virtual-func() private ist. Aber camper sagt "sollten sowieso", als ob du sie public hättest. Gehe mal deswegen davon aus das es nur ein vertipper war

Würde ich nicht von ausgehen

Private virtuals machen nämlich nicht gerade viel Sinn ...
In einem der Effectives steht was dazu drin. In der Tat machen private virtuals, die von public nonvirtuals aufgerufen werden, sehr viel Sinn.
EDIT: Herby schreibt folgendes: http://www.gotw.ca/publications/mill18.htm
-
LordJaxom schrieb:
Private virtuals machen nämlich nicht gerade viel Sinn ...
In einem der Effectives steht was dazu drin. In der Tat machen private virtuals, die von public nonvirtuals aufgerufen werden, sehr viel Sinn.
EDIT: Herby schreibt folgendes: http://www.gotw.ca/publications/mill18.htmAchso ok. Ich lese mir das mal später bzw. im Buch nochmal durch, wenn ich *wacher* bin

-
KasF schrieb:
Das bezieht sich doch auf deinen Code, wo aber virtual-func() private ist.
virtual void func() ist public!
@LordJaxom: danke für den Link, das dürfte camper wohl gemeint haben.
Zwar kann ich ihn verstehen, aber ich teile Sutters Ansichten in dieser Frage nicht generell. In diesem Fall wäre es aber wohl besser, wie camper vorschlägt:template <class T, void (T::*F) (void)> struct foo {}; struct bar { private: virtual void func_impl (void) { } public: void func (void) { func_impl (); } public: foo <bar, &bar::func> blub; };
-
audacia schrieb:
KasF schrieb:
Das bezieht sich doch auf deinen Code, wo aber virtual-func() private ist.
virtual void func() ist public!
Uuups, da steht ja struct. Sry
