Template :"Nur best Typen"
-
Baracke_out schrieb:
Der Clou wäre halt die Implementierung nicht zugänglich zu machen ausser von den Klassen
Hab ich doch mit nem protected gemacht...
wenn man von ner Klasse ableitet, dann wird man schon wissen, was man macht... Halte private / friend da für völlig übertrieben...bb
-
unskilled schrieb:
Aber die Lösung find ich toll[...]
Ich finde sie ziemlich hässlich...

-
Tachyon schrieb:
unskilled schrieb:
Aber die Lösung find ich toll[...]
Ich finde sie ziemlich hässlich...
Hab ich meinen Geschmack denn so am Arsch?
^^
Find sie eigtl so gar schöner als deine - aber naja...Ich zieh mich dann ma als Verlierer aus der Diskussion zurück ^^
bb : )
-
Jihhaaaa schrieb:
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); };Der Trick läuft unter SFINAE und wird durch das enable_if realisiert. So geht's mit boost:
#include <vector> #include <utility> // pair #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> // is_same #include <boost/mpl/or.hpp> class CStateEvent; typedef std::vector<std::pair<double,CStateEvent*> > t_vCont; typedef std::vector<std::pair<double,CStateEvent*> > t_lCont; template <class T_Cont> class CResourceAlloc { typedef typename boost::enable_if< typename boost::mpl::or_< typename boost::is_same< T_Cont, t_vCont>, typename boost::is_same< T_Cont, t_lCont> >, T_Cont >::type container_type; container_type m_lEvents; public: CResourceAlloc(); ~CResourceAlloc(); }; int main() { //CResourceAlloc< int > x; // compiliert nicht CResourceAlloc< t_vCont > y; return 0; };(getestet mit VS2005 und boost 1.35)
Leider funktioniert die Original-Variante (s.Kapitel 3.1) bei mir nicht, so ist es es eben doch ein (Compiler-)Fehler im Template, wenn man es mit einem anderen Typ versucht. Aber der Effekt ist der gewünschte - es compilieren nur die angegebenen Typen.
Gruß
Werner
-
Konstruktor und Destruktor von CResourceAlloc sollten vielleicht noch definiert werden.
Dann läufts bei mir auch mit gcc und BCB2007.
-
.. mit dem VS2008 funktioniert es in der gewünschten Weise
#include <vector> #include <utility> // pair #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> // is_same #include <boost/mpl/or.hpp> class CStateEvent; typedef std::vector<std::pair<double,CStateEvent*> > t_vCont; typedef std::vector<std::pair<double,CStateEvent*> > t_lCont; template< class T_Cont, class Enable = void > class CResourceAlloc; template <class T_Cont> class CResourceAlloc< T_Cont, typename boost::enable_if< typename boost::mpl::or_< typename boost::is_same< T_Cont, t_vCont>, typename boost::is_same< T_Cont, t_lCont> > >::type > { T_Cont m_lEvents; public: CResourceAlloc() : m_lEvents() {} ~CResourceAlloc() {} }; int main() { //CResourceAlloc< int > x; // Zeile 32 compiliert nicht: 'x' uses undefined class 'CResourceAlloc<T_Cont>' CResourceAlloc< t_vCont > y; return 0; };.. und die Fehlermeldung - falls Zeile 32 aktiviert wird - kommt dann auch in dieser Zeile. So sollte es sein.
Gruß
Werner
-
Aber jetzt mal ganz ehrlich: warum will man denn so eine restriktion in templates überhaupt haben? Damit killt man sich doch das größte pro argument für templates: wiederverwendbarkeit.
Templates sind eben nicht nur dafür da um sich schreibarbeit zu ersparen "ich will jetzt nicht für int und float dieselbe Klasse schreiben", sondern um das rad nicht andauernd neu erfinden zu müssen.Und viel bullshit kann man ohne solche restriktionen auch nicht machen. entweder es funktioniert, oder der compiler überschüttet einen mit kryptischen Fehlermeldungen. Was helfen die restriktionen dann?
//edit und mir is grad aufgefallen, dass die beiden typen beim threadstarter identisch sind...ahm typedefs mit verschiedenen namen und gleichem typ stellen den gleichen typ dar. Warum also ÜBERHAUPT ein template hier?
-
otze schrieb:
Templates sind eben nicht nur dafür da um sich schreibarbeit zu ersparen "ich will jetzt nicht für int und float dieselbe Klasse schreiben", sondern um das rad nicht andauernd neu erfinden zu müssen.
Aber das geht ja so auch... Klar ist es nicht die Grundidee der Templates, ich selber finde die Lösung auch nicht unbedingt die schönste, aber ich mein ja nur...
otze schrieb:
Und viel bullshit kann man ohne solche restriktionen auch nicht machen. entweder es funktioniert, oder der compiler überschüttet einen mit kryptischen Fehlermeldungen. Was helfen die restriktionen dann?
Naja, Hauptsache man kann kein Objekt erstellen (egal zu welchem Preis) :p
otze schrieb:
//edit und mir is grad aufgefallen, dass die beiden typen beim threadstarter identisch sind...ahm typedefs mit verschiedenen namen und gleichem typ stellen den gleichen typ dar. Warum also ÜBERHAUPT ein template hier?
Rate mal, wie oft das in diesem Thread schon gesagt wurde

Irgendwie hat sich daraus eine allgemeine Diskussion über eingeschränkte Templates entwickelt.
-
Guten Morgen allerseits,
hab mich bei den typedefs verschrieben, einmal vector, einmal list.
ich wollte ne Eventklassen Verwaltung (was ich nicht näher erklären möchte) einmal mit nem Vector Container compilieren, und einmal mit nem List Container... aber es mit nem template zu machen ist egentlich schwachsinn, da ich damit nur ohne viel aufwand das ding mit unterschiedlichen container performancetechnisch testen wollte..
-
hola
dann haettest das anders machen sollen:
typedef std::pair<double,CStateEvent*> mypair; template<class T> class CResourceAlloc { public: typedef T container; typedef container::iterator iterator; typedef container::const_iterator const_iterator; typedef container::size_type size_type; container con; }; CResourceAlloc<std::vector<mypair> > resource_alloc_vector; CResourceAlloc<std::list<mypair> > resource_alloc_list;hast jedoch unterschiedliche iterator-typen. also aufgepasst.
Meep Meep
-
Werner Salomon schrieb:
.. mit dem VS2008 funktioniert es in der gewünschten Weise[
Das funktioniert auch mit dem BCB2007. Soweit standardkompatibel ist der also auch schon.
-
Werner Salomon: in diesem falle bräuchte man wohl eher SFIAE - substitution failure *is* an error... lieber auf static_assert warten und währenddessen BOOST_STATIC_ASSERT verwenden.