Template :"Nur best Typen"



  • Was muss ich tun, damit nur t_cCont und t_lCont verwendbar sind für den Typ der Templateklasse?

    typedef std::vector<std::pair<double,CStateEvent*> > t_vCont;
    typedef std::vector<std::pair<double,CStateEvent*> > t_lCont;
    
    template <class T_Cont>
    class CResourceAlloc{
    
    	T_Cont m_lEvents;
    
    public:
    	CResourceAlloc(void);
    	~CResourceAlloc(void);
    };
    


  • du kannst zB mit boost.static assert und boost::is_same (aus type_traits) auf gleichheit des templates mit den gewünschten Klassen tippen.



  • Maxi schrieb:

    du kannst zB mit boost.static assert und boost::is_same (aus type_traits) auf gleichheit des templates mit den gewünschten Klassen tippen.

    Warum nicht typeof ?



  • -. schrieb:

    Warum nicht typeof ?

    Weil das erst zur Laufzeit greift?



  • Mit spezailisierung?



  • Weil es in C++ kein typeof gibt.



  • Mit spezailisierung?

    Dem ist nix mehr hinzuzufügen...

    bb

    PS: warum verschiedene typedefs für gleiche typen? Oo



  • unskilled schrieb:

    Mit spezailisierung?

    Dem ist nix mehr hinzuzufügen...

    ?



  • typedef std::vector<std::pair<double,CStateEvent*> > t_vCont; 
    
    #include <exception>
    
    template <class T>
    class CResourceAlloc
    {
    public:
    CResourceAlloc () throw (...)
      {
        throw std::invalid_argument ("Fehlermeldung");
     //oder
        throw std::bad_typeid ("Fehlermeldung"); //wahrscheinlich eher die...
      }
    }
    
    template < > 
     class CResourceAlloc <t_vCont>
      {
        private:
          T_Cont m_lEvents; 
    
        public: 
          CResourceAlloc(void); 
          ~CResourceAlloc(void); 
      };
    

    oder?

    bb

    edit:
    hatte std::std::...



  • Wohl kaum. Das kannst du so genauso gut unimplementiert lassen, dann gibt's einen (viel sinnvolleren) Compilerfehler.

    Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.



  • Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.

    Grund?



  • hustbaer schrieb:

    Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.

    Grund?

    Es wiederspricht dem Sinn von templates.



  • Mal ganz davon abgesehen, dass es einfach nicht geht. 😉

    Spezialisierung bedeutet, dass die Implementierung für bestimmte Fälle anders aussieht (die spezialisierten Fälle nämlich 😃 ), als es das normale Template vorsieht.
    Für alle nicht spezialisierten Fälle steht das Template trotzdem zur Verfügung, ob dies nun Sinn macht oder nicht.

    Wenn man nur eine begrenzte Menge an Typen hat, diese Menge aber so groß ist, dass es sich lohnt, dafür ein Template anzulegen, dann könnte man dafür das PIMPL Idiom benutzen.
    D.h. man erstellt das Template in einer Implementierungseinheit, ohne dessen Interface öffentlich zu machen.
    Öffentlich sind nur mehrere, spezialisierte Interfaces. Intern kann man dann verschiedene Ausprägungen des Templates benutzen, um die Funktionalitäten für die verschiedenen, spezialisierten Interfaces bereitszustellen.



  • @ Jihhaaaa:
    Wenn ein Template nur zwei Typen (typedefs) unterstützen soll und diese Typen dann auch noch identisch sind, ist eine normale, nicht-generische Klasse eher angebracht.



  • Wohl kaum. Das kannst du so genauso gut unimplementiert lassen, dann gibt's einen (viel sinnvolleren) Compilerfehler.

    Ok - da ist was dran ^^

    Aber ein Template, dass nur für eine endliche Anzahl Typen funktionieren soll ist Quark.

    Der OP wollte es für genau 2 Typen haben - entweder er schreibt 2 normale Klassen (was ich schwachsinnig fände) oder macht es so.
    Mal abgesehen aus dem (mir unerschließlichem) Grund - ich würds mit Spezialisierung machen... Und ich finde auch nicht, dass es dem Konzept der Templates wiederspricht - das template ist für den Fall spezialisiert und für einen anderen Fall halt nicht definiert - hab noch nicht gelesen, dass das nicht gehen soll...

    bb



  • unskilled schrieb:

    ...das template ist für den Fall spezialisiert und für einen anderen Fall halt nicht definiert - hab noch nicht gelesen, dass das nicht gehen soll...bb

    Wie willst Du das durch Spezialisierung hinbekommen? Insbesondere den Teil, dass ein Template für die nichtspezialisierten Fälle nicht definiert ist?

    Spezialisierung ist nicht dafür da, die Benutzbarkeit eines Templates einzuschränken.
    Sie soll die Funktionalität für ein Subset von Typen in bestimmter Weise implementieren. Wenn Du nur zwei spezialisierte Templates zur Verfügung stellt, aber das allgemeine weglässt, dann kannst Du in der Tat auch normale Klassen benutzen.



  • Tachyon ich denke dieses einfach Template könnte deine Frage beantworten.

    template<bool> struct CTAssert;
    template<> struct CTAssert<true> {};
    

    Spezialisierung mit einer Forward-Deklaration kann aber dazu verwendet werden die Benutzbarkeit des Templates einzuschränken. Und in dem Beispiel oben ist es auch duraus sinnvoll. Auch wenn das Compilt-Time-Assert auch schöner imlementiert werden kann.

    Quelle: http://safari.ibmpressbooks.com/0201704315/pref01 und soweit ich weiss steht es auch in "Modern C++ Design", welches ich aber nur teilweise gelesen habe.

    Gruß
    Baracke



  • Baracke_out schrieb:

    [...]

    Das ist ein ganz anderer Sinnzusammenhang.

    Ich lasse mich allerdings gerne eines besseren belehren, wenn Du mir ein Beispiel für ein Template gibst (vielleicht ein Mini-Container), das mit genau zwei Typen ( double und struct MyType{}; ) funktioniert, sonst aber mit keinem anderen Typen.



  • Naja... Nicht ganz so elegant, aber es geht...

    template <class T>
    	class test
    		{
    			private:
    				test () {};
    		};
    
    template < >
    	class test <char>
    		{
    			public:
    				test () {};
    		};
    
    int main ()
    	{
    		test <bool> eins; //fehler
    		test <int> zwei; //fehler
    		test <char> drei; //geht
    	}
    

    Allerdings würde ich dann doch lieber meine Lösung von vorn mit der Exception bevorzugen ^^

    Aber recht geben muss ich dir dann ja wo trotzdem, für den Fall, dass du das nicht zählst ^^

    bb

    edit:
    mir ist noch ne lösung eingefallen - aber besser ist sie wahrscheinlich auch nicht xD
    wenn man dann die funktion noch iwie in "invalid_template_argument" umbennent könnte man es so gar fast als benutzerfreundlich zählen 😉

    void get_linker_error ();
    
    template <class T>
    	class test
    		{
    			public:
    				test ()
    					{
    						get_linker_error ();
    					};
    		};
    
    template < >
    	class test <char>
    		{
    			public:
    				test ()
    					{}
    		};
    
    int main ()
    	{
    		test <bool> eins;
    		test <int> zwei;
    		test <char> drei;
    	}
    

    PS: weiß nicht, ob #pragma da vll ne bessere möglichkeit bietet - aber das wär halt dann auch wieder msvc spezifisch...



  • unskilled schrieb:

    Naja... Nicht ganz so elegant, aber es geht...

    template <class T>
    	class test
    		{
    			private:
    				test () {};
    		};
    
    template < >
    	class test <char>
    		{
    			public:
    				test () {};
    		};
    
    int main ()
    	{
    		test <bool> eins; //fehler
    		test <int> zwei; //fehler
    		test <char> drei; //geht
    	}
    

    Allerdings würde ich dann doch lieber meine Lösung von vorn mit der Exception bevorzugen ^^

    Aber recht geben muss ich dir dann ja wo trotzdem, für den Fall, dass du das nicht zählst ^^

    bb

    Wie gesagt, ich hätte gerne einen Container für die beiden genannten Typen. Er soll mit seiner Template-Implementierung genau die zwei Typen zulassen. Alle anderen aber nicht. Die hier gezeigten Beispiele sind Spezialimplementierungen für die Spezialisierung.

    Dein Beispiel hat z.B. die allgemeine Implementierung mit dem Private-Ctor und eine spezialialisierte Version für char mit eigener Implementierung. Für weitere, zulässige Typen müsstest Du weitere Implementierungen bereitstellen.
    Du musst also für N Typen auch N Implementierungen spezialisieren, sowie denn allgemeinen Fall verbieten. Der Fall tes TOs ist sogar noch schlimmer, da die beiden Typen die gleiche Implementierung benutzen sollen. Man muss also zwei Spezialisierungen schreiben, die die gleichen Algorithmen beinhalten. Dann kann man auch gleich zwei Klassen schreiben, und sich das verbieten von nicht erwünschten Typen sparen.

    Mal ganz davon abgesehen sind, so wie ich das jetzt sehe, die beiden Typen mit denen der TO sein Template ausprägen will in Wirklichkeit nur ein Typ.


Anmelden zum Antworten