template typen einschränken



  • Sovok schrieb:

    ich möchte, dass n bestimmtes template nur mit standardtypen oder pointern auf klassen/structs verwendet wird
    nicht aber mit klasseninstanzen die keine pointer sind

    kann ich das irgendwie einschränken, dass der compiler ne meldung bringt wenn jemand versucht das template mit ner klasse auf dem stack zu verwenden?

    Schau dir Boost static_assert und Boost type_traits an. Bei der Dokumentation von type_traits ist sogar ein Beispiel.



  • ::boost::is_integral<T>::value
    ::boost::is_float<T>::value
    ::boost::is_pointer<T>::value

    sieht gut aus aber wie arbeitet des zeuch intern?
    ich hab kein boost auf meinen plattformen verfügbar

    nur standard c/c++



  • Sovok schrieb:

    sieht gut aus aber wie arbeitet des zeuch intern?

    Ich denke, das funktioniert so ähnlich wie auch die Loki-TypeTraits (hab Boost-TypeTraits nur mal überflogen *duck*) über vollständige oder partielle Template-Spezialisierung (siehe Link von oben).

    Aus der Loki-Bib. könntest du z.B.
    TypeTraits<T>::isStdFundamental
    (returns (at compile time) true if T is a standard fundamental type) und
    TypeTraits<T>::isPointer
    (returns (at compile time) true if T is a pointer type) benutzen.



  • fubar schrieb:

    Aus der Loki-Bib. könntest du z.B.
    TypeTraits<T>::isStdFundamental
    (returns (at compile time) true if T is a standard fundamental type) und
    TypeTraits<T>::isPointer
    (returns (at compile time) true if T is a pointer type) benutzen.

    das is doch der punkt... wie find ich raus obs n pointer is?
    ich blick das nich

    ps: is fundamental das gegenteil von pointer bzw. aufm stack?



  • #include <iostream>
    
    template <class T>
    struct TypeTraits
    {
    	private:
    		template <class U> struct PointerTraits
    		{
    			enum { result = false };
    		};
    		template <class U> struct PointerTraits<U*>
    		{
    			enum { result = true };
    		};
    	public:
    		enum { isPointer = PointerTraits<T>::result };
    };
    
    class TestClass
    {};
    
    int main()
    {
    	std::cout << TypeTraits<TestClass >::isPointer << std::endl;
    	std::cout << TypeTraits<TestClass*>::isPointer << std::endl;
    }
    

    isStdFundamental bedeutet Fließkomma-, Ganzzahltyp oder void.



  • kann ich das zur kompilier oder linkzeit noch abfangen falls
    isPointer == false is?



  • Ja, das geht IMHO z.B. so:

    #include <iostream>
    #include <loki/static_check.h>
    #include <loki/TypeTraits.h>
    
    class TestClass
    {};
    
    template <typename T>
    void function(T t)
    {
    	STATIC_CHECK(Loki::TypeTraits<T>::isPointer, NOT_A_POINTER);
    }
    
    int main()
    {
    	TestClass c1;
    	function(c1); //gibt Fehler beim Kompilieren
    
    	TestClass* c2 = new TestClass();
    	function(c2); //funktioniert
    }
    

    STATIC_CHECK sieht so aus: http://www.visualco.de/idiom/samples/Loki/html/c$$libLokiLokiReference$static_che69.html

    Vielleicht könnte man das aber auch anders (== besser) lösen?!?



  • kann ich das zur kompilier oder linkzeit noch abfangen falls
    isPointer == false is?

    Ja so:

    tempalte<class T,int size=sizeof(T)>
    class A;
    tempalte<class T>
    class A<T,4>{
      //...
    };
    

    So muss T 4 byte gross sein. Das ganze kannst do aber auch mit bool machen:

    tempalte<class T,int blalba=is_foo<T>::result>
    class A;
    tempalte<class T>
    class A<T,1>{
      //...
    };
    

    Somit mus T foo sein.



  • fubar schrieb:

    Ja, das geht IMHO z.B. so:

    TestClass c1;
    	function(c1); //gibt Fehler beim Kompilieren
    	
    	TestClass* c2 = new TestClass();
    	function(c2); //funktioniert
    

    habs jetzt schon ein paar mal nachgebaut... klappt aber nicht

    ich kann feststelln obs n long,bool oder sonst ein standard typ is

    aber die unterscheidung zwischen klasse und klassenpointer klappt nicht



  • Ich glaube, es gibt Portierungen für viele Compiler; welchen benutzt du? Lad dir doch mal die Loki-Bib. herunter, und teste, ob vielleicht eine der Portierungen funktioniert?!?



  • ich kann feststelln obs n long,bool oder sonst ein standard typ is
    aber die unterscheidung zwischen klasse und klassenpointer klappt nicht

    Vielleicht kennt dein Compiler die dazu nötige partielle Spezialisierung nicht?

    ansonten

    template <typename T>
    struct IsPointer {
       enum {value = false};
    };
    
    template <typename T>
    struct IsPointer<T *> {
       enum {value = true};
    };
    

Anmelden zum Antworten