welchen Vorteil hat ein Funktions Template Gegenüber Konstruktur?



  • Welchen Vorteil hat:

    template<typename T, int(*fun)(T)>
    class example
    {
        example(){
    
        }
    
        int exampleFun(T t){
           return fun(t);
        }
    }
    

    gegenüber

    template<typename T>
    class example
    {
        int(*fun)(T);
        example(int(*fun2)(T)){
            fun=fun2;
        }
    
        int exampleFun(T t){
           return fun(t);
        }
    }
    


  • Bei letzteren erfolgt der Funktionsaufrief über eine Indirektion, den Funktionspointer. Dauert ein paar Microsekúnden länger. Kann aber möglicherweise auch weg optimiert werden.


  • Mod

    Die beiden machen verschiedene Dinge. Man kann nicht sagen, dass eines davon pauschal besser oder schlechter wäre. Man kann auf einen konkreten Anwendungsfall bezogen sagen, welches besser oder schlechter dafür geeignet ist, wobei die Antwort aber für die meisten Anwendungsfällen recht schwarz/weiß ausfallen dürfte, also dass eines geeignet und das andere komplett ungeeignet ist.

    Man könnte natürlich auch die Unterschiede zwischen den beiden aufzählen, für den Fall, dass dies deine eigentliche Frage sein sollte.



  • Danke für die schnellen Anworten.

    Meine eigentlich Frage ist:
    https://www.c-plusplus.net/forum/342804

    Das hier wäre nur eine alternative Lösung.

    Ich möchte eine Klasse schreiben, die eine Funktion verwendet, die wiederum abhängig von (zur Laufzeit ermittelten) Werten ist. Und suche nach den besten Weg dies zu tun.

    möglich wäre auch noch

    template<typename A, typename B>
    fun(A a, B *b){
       //code hier
    }
    
    template<typename A, typename B, B *werte>
    fun(A a){ 
       return fun(a, werte)
    }
    

    Könnte man das noch kurzer machen? "typename B" steht nur da um einen pointer von diesen Typ zu übergeben. Wenn ich richtig liege, wäre diese Alternative jedoch wieder ein paar Millisekunden langsammer, als wenn die Funktion direkt im Template ist.



  • Möglicherweise suchst du std::function .


  • Mod

    Wenn die Funktion dynamisch zur Laufzeit ist, dann ist die Antwort, wie erwartet, schwarz/weiß. Denn dann geht die erste Lösung überhaupt gar nicht. Das heißt aber noch nicht zwangsweise, dass die andere Version auch "die Beste" ist. Dafür muss ich mal genauer über das konkrete Problem nachdenken.



  • Oh, die Möglichkeit mit dem Werte Pointer geht auch nicht, da dieser auch konstant sein müsste.

    ---
    std::function in das template? Das ist doch zumindest in diesem Fall nur schöner aufgeschrieben, oder?

    --
    @dynamisch zur Laufzeit
    Die Klasse selbst verwendet jedoch immer konstant die gleiche. Die zu verwendente Funktion ist also vor dem Erstellen der Klasse (beim Ausführen des Programmes) bekannt. Ist also während die Klasse etwas tut konstant.



  • globale Variablen würden noch gehen.
    Aber das will man ja nach Möglichkeit vermeiden.



  • std::function speichert einen Funktor, Lambdaobjekt oder einen Zeiger auf eine Funktion. Unabhängig davon, was nun tatsächlich gespeichert ist, kannst du nun einfach die gespeicherte Funktion aufrufen. Am Ende auch nur Variante zwei in besser.



  • mgaeckler schrieb:

    Bei letzteren erfolgt der Funktionsaufrief über eine Indirektion, den Funktionspointer. Dauert ein paar Microsekúnden länger.

    Echt? Eine Indirektion kostet ein paar Microsekunden (nicht Nanosekunden) auf einer aktuellen CPU?



  • Natürlich keine Mikrosekunde, ansonsten wäre Polymorphie ja verdammt teuer.


  • Mod

    Kann aber theoretisch auch sein, dass es viel mehr ausmacht, da bei der statischen Variante der Funktionsaufruf zur Compilezeit geinlined werden kann, was ganz andere Optimierungsmöglichkeiten über Funktionsgrenzen hinweg eröffnet.


Log in to reply