//template - lösung für a local variable cannot be used as a non-type argument?
-
/////////////////////////////////////////////////////////////////////////////// //Aus "C++ Templates - The Complete Guide" // primary template: yield second or third argument depending on first argument template<bool C, typename Ta, typename Tb> class IfThenElse; // partial specialization: true yields second argument template<typename Ta, typename Tb> class IfThenElse<true, Ta, Tb> { public: typedef Ta ResultT; }; // partial specialization: false yields third argument template<typename Ta, typename Tb> class IfThenElse<false, Ta, Tb> { public: typedef Tb ResultT; }; /////////////////////////////////////////////////////////////////////////////// //MEIN STUFF namespace XXX{ enum Modell { FIRST=0, SECOND=1 }; template< int Modell, bool AInsteadOfB> class MyModelTrait{ public: typedef typename IfThenElse< AInsteadOfB , A, B >::ResultT Test1; }; //partielle Spezialisierung für Modell=FIRST template< bool AInsteadOfB > class MyModelTrait< FIRST, AInsteadOfB >{ public: typedef typename IfThenElse< AInsteadOfB , A, B >::ResultT Test1; typedef MyModelClassFIRST ModelClass; }; //partielle Spezialisierung für Modell=SECOND template< bool AInsteadOfB > class MyModelTrait< SECOND, AInsteadOfB >{ public: typedef typename IfThenElse< AInsteadOfB , A, B >::ResultT Test1; typedef MyModelClassSECOND ModelClass; }; }Soweit so gut. Dass das Snipet relativ sinnfrei ist, ist mir bewußt (hier koennte bsp-weise man MyModelClassSECOND direkt als template Argmument übergeben). Darum geht es mir aber gar nicht.
Was mich interessiert ist folgendes:
kann man das Problem mit "a local variable cannot be used as a non-type argument" irgendwie austricksen? So dass man zur Laufzeit Instanzen abhaenig von Variablen erzeugen kann?sowas wie:
{ bool val1=true; MyModelTrait<FIRST,val1> obj; }natürlich muss hierfür die Definiton von MyModelTrait<FIRST,true> beim Kompilieren bekannt sein. Wie geht man bei sowas am geschicktesten vor?
-
Laufzeitpolymorphie?
Das ist schließlich sowas wie das „natürliche Analogon“ zur Compilezeitpolymorphie.
-
naja, bisher verwende ich sowas wie:
template< typename ModelTrait> class B{ B() { MyModelTrait::ModelClass model; MyModelTrait::Test1 test; } }; template<int Modell> SmartPtr<B> getCreatorForModel(bool AinsteadB); template<> SmartPtr<B> getBPtr<FIRST>(bool AinsteadB) { if(AinsteadB) return SmartPtr<B>(new B<FIRST,true>()); return SmartPtr<B>(new B<FIRST,false>()); }das muss doch irgendwie zu automatisieren sein!
nachtrag: es gibt derzeit 8 modelle und class B repräsentiert ein Modul, dass diverse parameter in abhängigkeit des models setzt. mittels traits werden vier verschiedene module (nennen wir sie C1...C3) deklariert, die sich nur im Typ von denen der anderen modelle unterscheiden. diese module sind auch temmplates, die eben mit A oder B belegt werden konenen.
Also behandelt class B sowas wie folgende Fälle:B<FirstModel, FirstModelC1<A>, FirstModelC2<A>, FirstModelC3<A> > a(); B<FirstModel, FirstModelC1<A>, FirstModelC2<B>, FirstModelC3<B> > b(); B<FirstModel, FirstModelC1<B>, FirstModelC2<A>, FirstModelC3<A> > c(); B<FirstModel, FirstModelC1<B>, FirstModelC2<B>, FirstModelC3<B> > d(); B<SecondModel, SecondModelC1<A>, SecondModelC2<A>, SecondModelC3<A> > a(); B<SecondModel, SecondModelC1<A>, SecondModelC2<B>, SecondModelC3<B> > b(); B<SecondModel, SecondModelC1<B>, SecondModelC2<A>, SecondModelC3<A> > c(); B<SecondModel, SecondModelC1<B>, SecondModelC2<B>, SecondModelC3<B> > d(); C....die Klasse B lies sich wunderbar mit traits erschlagen. Zudem existiert eine BasisKlasse BaseB.
Je nachdem welche Parameter man braucht wird die Klasse B als Strategy-Object zu einer anderen Klasse hunzugefügt (eben über den Basisklassen-Ptr). Und nun möcht eich noch ein eFunktion schreiben, die mit in Abhängigkeit von Model, A und B die entsprechende Instanz von B<Model, A, B> erzeugt...