Multiplikation mit Templates



  • dghdfg schrieb:

    ...float, double, etc. funktioniert?

    Nein. Als Nicht-Typ-Template-Parameter werden nur Ganzzahltypen, Zeiger und Referenzen unterstützt. Letztere nur auf "statische" Objekte / Funktionen mit externer Bindung.

    Was willst Du denn eigentlich machen?



  • Das würde dann so gehen:

    #include <iostream>
    
    template <typename T, const T a, const T b>
    struct Mul {
    	static const T value = a * b;
    };
    
    int main() {
    	std::cout << Mul<int, 10, 10>::value << "\n";
    	//std::cout << Mul<float, 5.5, 3.3>::value << "\n"; das geht leider nicht..
    }
    

    Nur leider bei float und double nicht, wie das Internet sagt:

    internet schrieb:

    > A template-argument for a non-type, non-template template-parameter
    > shall be one of:
    > — an integral constant-expression of integral or enumeration type; or
    > — the name of a non-type template-parameter; or
    > — the address of an object or function with external linkage,


  • Mod

    Theoretisch müsste man die Rechnung mit floats durch die Rechnung mit Integern emulieren können. Das dürfte auch gar nicht soooo schwierig sein, aber zu viel Arbeit als das ich damit einen Sonntag Nachmittag verbringen möchte. Viel Spaß dabei an Interessierte.



  • Welchen Sinn hat das bitte?

    template<typename T>
    T mult(T a, T b)
    {
       return a*b;
    }
    
    std::cout << "Result: " << mult<float>(10,10) << std::endl;
    

    Ist das selbe und geht mit allen Typen..
    Sorry aber ich verstehe es nicht^^.


  • Mod

    Scorcher24 schrieb:

    Ist das selbe und geht mit allen Typen..
    Sorry aber ich verstehe es nicht^^.

    Einstieg in die Template-Metaprogrammierung? Man muss eben klein anfangen.



  • Naja er sagte aber

    dghdfg schrieb:

    [...] wie schaffe ich es, dass ich ein Template schreibe [...]

    Insofern hat Scorcher24 schon Recht, es muss ja nicht unbedingt so "kompliziert" sein. Und Template-Metaprogrammierung sollte man erstmal auslassen wenn man allgemein mit templates anfängt. Zumindest sieht das mein Buch auch so 😉

    Ps. Buch: Der C++ Programmierer



  • SeppJ schrieb:

    Einstieg in die Template-Metaprogrammierung? Man muss eben klein anfangen.

    Trotzdem darf man auch mal vernünftige Beispiele für Template-Metaprogrammierung wählen 😉

    Sowas wie eine Compilezeit-Fakultät ist zwar gut, um das Prinzip (funktionale Programmierung mit Templates) zu sehen, wird aber nie eingesetzt werden. Für sinnvolle Anwendungen kann man z.B. was mit Traits machen...



  • SeppJ schrieb:

    Scorcher24 schrieb:

    Ist das selbe und geht mit allen Typen..
    Sorry aber ich verstehe es nicht^^.

    Einstieg in die Template-Metaprogrammierung? Man muss eben klein anfangen.

    Gut, wenn er das lernen möchte dann nur zu :D.
    Hab das überlesen mit dem Expermiment und das Beispiel sah ein wenig sinnbefreit aus in MEINEN Augen. Ich vermeide sowas wo es nur geht bzw nutze es gar nicht.
    Einfacher Code ftw.
    Nur meine Meinung.



  • Nexus schrieb:

    Sowas wie eine Compilezeit-Fakultät ist zwar gut, um das Prinzip (funktionale Programmierung mit Templates) zu sehen, wird aber nie eingesetzt werden.

    Es sei denn es geht drum, die Laufzeit zu verkürzen und das gesamte Provlem schon zur Compilezeit durchrechnen zu lassen 😉
    Oder weil man den Ehrgeiz hat (oder so verspielt ist), etwas auch mal per TMP zu lösen.
    (Nur zu dumm dass die Verschachtelungstiefe bei Templates meist viel zu schnell erreicht ist...)



  • Du kannst Fliesskommazahlen statisch emulieren durch rationale Zahlen oder besser noch durch Kettenbrüche. Es gibt auch libs und boost.mpl Erweiterung die genau sowas machen.

    Ein Beispiel wäre

    template< class T , T Numerator , T Denominator >
    struct rational_number
    {
        typedef T value_type;
        typedef rational_number type;
    
        const static value_type numerator = Numerator;
        const static value_type denominator = Denominator;
    };
    

    Auf diese Werte der Zahl kannst Du dann in etwa so:

    template< class Num >
    struct conv
    {
        static double get_value( void )
        {
            return static_cast< double >( Num::value );
        }
    };
    
    template< class T , T Numerator , T Denominator >
    struct conv< rational_number< T , Numerator , Denominator > >
    {
        typedef rational_number< T , Numerator , Denominator > num_type;
        static double get_value( void )
        {
            return static_cast< double >( num_type::numerator ) / static_cast< double >( num_type::denominator );
        }
    };
    
    int main()
    {
        typedef rational_number< long , 1 , 2 > one_half;
        cout << conv< one_half >::get_value() << endl;
    }
    

    Ich schrieb übrigens gerade einen kleine Artikel über dieses Thema (und mehr) für das Magazin hier. Sollte bald fertig sein.



  • Mach doch Multiplikation durch wiederholte Addition und Addition durch wiederholtes Inkrement 😃


Anmelden zum Antworten