Funktions-Komposition



  • Hi,

    aus lauter spass habe ich mal eine Funktionskomposition gebastelt:

    template <typename T1, typename T2, typename T3>
    T3 compose (T2 (*function1_type)(T1), T3 (*function2_type)(T2), T1 x) {
        return (*function2_type)((*function1_type)(x));
        }
    

    geht das auch noch eleganter?

    template <typename T1, typename T2, typename T3>
    T3 (*compose(T2 (*function1_type)(T1), T3 (*function2_type)(T2))) (T1) {
        ...
        }
    

    😕
    return (compose(function1_type, function2_type));
    klappt leider nicht ... 🙄

    Vielen Dank



  • Was genau klappt denn nicht? Ich tippe mal, daß der Compiler Probleme hat, die richtigen Typen festzustellen.

    PS: Weil sowas mit Funktionen tatsächlich etwas unelegant wird, gibt es in C++ sog. "Funktoren". In der STL gibt es zwar keine Compose-Funktoren, aber in meinem Artikel "Aufbau der STL 3" habe ich ein Beispiel für einen compose() vorgestellt.



  • Hallo CStoll,

    der compiler nimmt es, zur laufzeit bleibt das Programm bei der Zeile

    char (*f_composed_g)(double) = compose<double,int,char> (g,f);

    einfach stehen, als ob es auf eine Eingabe wartet 🙄
    Gibt es einen Link zu deinem Artikel?

    Dankeschoen 🙂



  • Funktionierer schrieb:

    Hallo CStoll,

    der compiler nimmt es, zur laufzeit bleibt das Programm bei der Zeile

    char (*f_composed_g)(double) = compose<double,int,char> (g,f);

    einfach stehen, als ob es auf eine Eingabe wartet 🙄

    Irgendwie blicke ich durch deine Codes auch nicht mehr durch. Kannst du das mal übersichtlicher zusammenfassen?

    Gibt es einen Link zu deinem Artikel?

    Klar: den findest du im C++ Magazin



  • Danke fuer den Link.
    Mein Code ist ganz einfach:

    template <typename T1, typename T2, typename T3>
    T3 compose (T2 (*function1_type)(T1), T3 (*function2_type)(T2), T1 x) {
        return (*function2_type)((*function1_type)(x));
        } 	
    
    template <typename T1, typename T2, typename T3>
    T3 (*compose(T2 (*function1_type)(T1), T3 (*function2_type)(T2))) (T1) {
        return (compose(function1_type, function2_type)); 
        }
    

    Naja und jetzt ein main-Programm zum Testen:

    char f(int d) {
        ...
        }
    
    int g(double d) {
        ...
        }
    
    int main (int argc, char *argv[]) {
    
        cout << compose<double,int,char>(g,f,2.2) << endl;
        char (*f_composed_g)(double) = compose<double,int,char> (g,f);
    
        }
    

    compose<double,int,char>(g,f,2.2) klappt, bei char (*f_composed_g)(double) = compose<double,int,char> (g,f); bleibt das Programm stehen 🙄



  • Ja, da hast du auch eine nette Endlos-Rekursion eingebaut:

    //mal etwas vereinfacht:
    T compose(T1 x1,T2 x2)
    {
      return compose(x1,x2);
    }
    

    ^^siehst du etwas? Die Funktion ruft sich selber auf - und da sie keine Abbruchbedingung hat, macht sie das so lange, bis dir der Stack um die Ohren fliegt.


Anmelden zum Antworten