Template nur Zahlen möglich



  • icarus2 schrieb:

    Aber dass NUR Zahlen als Parameter verwendet werden dürfen ohne doppelten Code zu verwenden. Geht das? Wenn ja vielleicht ein ganz kurzes Beispiel?

    #include <iostream>
    #include <string>
    using namespace std;
    
    template<typename T>
    class Foo{
    	static const T dummy=T()+T()*T();//Wird abkacken, wenn + und * nicht gehen
    	...//und hier der noemale Code
    };
    
    int main()
    {
    	Foo<double> g;
    //	Foo<string> s;
    	return 0;
    }
    

    Das erlaubt, daß dein Code noch mit Rational oder std::complex und so geht. Ich denke, das ist so beabsichtigt.



  • Naja... weil es in meinem Fall nicht wirlich sinnvoll ist andere Werte zu nehmen (kann sogar zu Fehlern führen).

    Da wollte ich fragen ob mein Ansatz schlecht ist, sowas in die Dokumentatino gehört oder wie man das sonst löst.

    Kurze Erklärung:
    Ich versuche gerade möglichst abstrakt eine Schnittstelle für das Bewegen von Objekten zu schaffen. Es soll dann erst in der Implementierung entschieden werden für welchen Typ man sich entscheidet.

    *Edit (Hab einige Beiträge erst jetzt gsehen)
    @drakon
    Ich schau mir das mal an. Es macht einfach nicht wirklich sinn da andere Parameter. Gut, vielleicht müsste da wirklich auch der, der die Implementierung schreibt daran denken.

    @mmmm
    Das wäre eigentlich eine Möglichkeit. Das einzige, was ich eigentlich nicht wollte war die value_ Variable private zu haben, aber eigentlich ist das gar nicht so schlecht. (Halt noch von Java an Interfaces gewohnt ^^)

    @volkard
    Durch das static const T dummy=T()+T()*T() wird dann verlangt, dass diese Operatoren unterstützt werden, richtig?



  • icarus2 schrieb:

    Da wollte ich fragen ob mein Ansatz schlecht ist, sowas in die Dokumentatino gehört oder wie man das sonst löst.

    Dokumentation ist da der übliche Weg.



  • Oki, dann mach ich das so.

    Danke für eure Beiträge.



  • Ah, so meinst du das. Ja, das geht auch, ist aber etwas komplizierter. Zuerst schreibst du dir mittels Template-Spezialisierung eine kleine Metafunktion, welche prüft, ob zwei Typen gleich sind:

    template <typename T, typename U>
    struct IsSame
    {
    	static const bool Value = false;
    };
    
    template <typename T>
    struct IsSame<T, T>
    {
    	static const bool Value = true;
    };
    

    Anschliessend noch ein Static-Assert, das eine Bedingung zur Kompilierzeit prüft (bei Condition == false wird ein Kompilierfehler ausgelöst, da das Template für diesen Fall nicht definiert ist):

    template <bool Condition>
    struct StaticAssert;
    
    template <>
    struct StaticAssert<true>
    {
    };
    

    Und dann irgendwo in der Art instanziieren ( sizeof schaut sich einen Ausdruck oder Typ an, ohne ihn komplett auszuwerten):

    sizeof( StaticAssert<
            IsSame<T, int>::Value
         || IsSame<T, double>::Value
         || IsSame<T, float>::Value > );
    

    Ist natürlich etwas viel Code, aber wenn du z.B. Boost hast, können dir die Type-Traits fast alles abnehmen. Da gibts noch Typlisten und jenste Möglichkeiten, aber das dürfte schonmal reichen. 😉



  • volkard schrieb:

    template<typename T>
    class Foo{
    	static const T dummy=T()+T()*T();//Wird abkacken, wenn + und * nicht gehen
    	...//und hier der noemale Code
    };
    

    Das funktioniert nur für integrale Typen, da Konstanten anderer Typen nicht in der Klassendefinition initialisiert werden dürfen. Also entweder in eine wichtige Methode packen (wichtig, weil der Compiler nicht benutze Funktionstemplates nicht vollständig analysiert und es daher durchgehen lassen könnte) und vielleicht mit sizeof den Dummy einsparen, oder direkt einen anderen Weg gehen.



  • Ahh, so langsam fange ich an dieses Metazeugs zu lieben. Es erfordert etwas anderes Denken, aber es scheint echt nützlich zu sein. 🙂



  • So, endlich mal wieder Zeit hier reinzuschauen.

    Habe gerade etwas Mühe das Beispiel zu verstehen, ist wirklich etwas kompliziert ^^

    Zum ersten Code-Snippet:
    Wenn die Typen nicht gleich sind, dann wird Value false (weil das obere IsSame zum Zug kommt). Sind sie gleich, dann wird das untere genommen und Value ist true?

    Zum zweiten Code-Snippet:
    Du sagst da einfach, dass die bool Condition true sein muss weil es für false nicht definiert ist?

    Zum dritten Code-Snippet:
    Sobald ein Value false ist, wird der gesamte Ausdruck false ==> Typen nicht gleich ==> Compilfehler?

    Habe ich das richtig verstanden?



  • Genau so ist es.



  • Alles klar, vielen Dank euch 🙂


Anmelden zum Antworten