Funktion als Rückgabetyp



  • mgaeckler schrieb:

    Funktionen können weder als Parameter an eine Funktion übergeben werden, noch zurückgeliefert werden, da es den Datentyp function oder wie auch immer das genannt werden soll, nicht gibt.

    Da du den neuen Standard erwähnt hast, was ist mit std::function?


  • Mod

    mgaeckler schrieb:

    Funktionen können weder als Parameter an eine Funktion übergeben werden, noch zurückgeliefert werden, da es den Datentyp function oder wie auch immer das genannt werden soll, nicht gibt.

    Das ist auf subtile Weise richtig. Es gibt Funktionstypen, aber Funktionstypen sind keine Objekttypen (oder Datentypen wenn du sie so nennen willst).



  • Fällt jmd. zufällig auch ein Beispiel ein an wo so etas Sinn macht?

    Unter reinem c++ wohl eher seltener, weil es fuer c++ bessere Mittel gibt (Interfaces / virtualitaet).
    bleibt C und C kompatiblitaet mit c++ ....

    bei C wird man aber wohl eher keinen funktionspointer als rueckgabewert waehlen, sondern eher den Fehlercode, der eigentliche rueckgabewert ist dann in den paramatern als zeiger auf ... modeliert.

    Ciao ...



  • set_new_handler Ist z.B. eine Funktion aus dem C++-Standard, die einen Funktionspointer zurückgibt. Gibt afaik noch ein paar andere...



  • set_unexpected und set_terminate fallen mir da ein.



  • redrew99 schrieb:

    Eine Funktion als Rückgabewert ist schon ziemlich abgefahren... 😃
    Fällt jmd. zufällig auch ein Beispiel ein an wo so etas Sinn macht?

    Mal so ein Vorschlag:

    qsort erwartet als einen der Parameter die Adresse einer Vergleichsfunktion. Dummerweise wird weder der Vergleichsfunktion noch qsort das Sortierkriterium mitgegeben. Daher wäre folgenden Szenario denkbar:

    typedef int (*comparePtrType)( const void *e1, const void *e2 );
    
    int compareNames( const void *e1, const void *e2 );
    int compareSizes( const void *e1, const void *e2 );
    int compareAges( const void *e1, const void *e2 );
    
    comparePtrType getCompareFunc( int criteria )
    {
       switch( criteria )
       {
          case 0:
             return compareNames;
          case 1:
             return compareSizes;
          case 2:
             return compareAges;
       }
    
       return NULL;
    }
    
    void sortData( void *data, size_t numElements, size_t dataSize, int criteria )
    {
       comparePtrType compareFunc = getCompareFunc( criteria );
       if( compareFunc )
          qsort( data, numElements, dataSize, comparefunc );
    }
    

    Hab's jetzt nicht übersetzt sondern nur so hingeschrieben. Tippfehler müsst Ihr daher selbst beheben.

    mfg Martin



  • mgaeckler schrieb:

    qsort erwartet als einen der Parameter die Adresse einer Vergleichsfunktion. [...]

    /* viel C-Code... */
    

    Macht man in C++ komplett anders. Templates statt void-Pointern, und das Vergleichskriterium hängt man dann auch eher in einen Functor.



  • pumuckl schrieb:

    mgaeckler schrieb:

    qsort erwartet als einen der Parameter die Adresse einer Vergleichsfunktion. [...]

    /* viel C-Code... */
    

    Macht man in C++ komplett anders. Templates statt void-Pointern, und das Vergleichskriterium hängt man dann auch eher in einen Functor.

    Klar, nur wollte jemand ein einigermassen sinnvolles Bespiel. Mir ist halt auf die schnelle nix beseres eingefallen.

    mfg Martin



  • mgaeckler schrieb:

    Zum Derefenezieren des Funktionszeigers schreibst Du den Namen des Zeigers mit Parameterliste:

    Beispiel:

    int result = comparePtr( "Hello", "World" );
    

    Nö. Funktionszeiger funktionieren genau wie normale Zeiger auch, bloß sind sie umständlich zu deklarieren.

    typedef vector<string> Function(int, double);
    Function*  func_ptr    = some_func; // einzig hier ist der Adressoperator optional
    Function&  func_ref    = *func_ptr;
    Function&& func_refref = std::move(func_ref); // klingt unlogisch, ist es auch
    

  • Mod

    314159265358979 schrieb:

    Function&& func_refref = std::move(func_ref); // klingt unlogisch, ist es auch
    

    Auf die Schnelle kann nicht finden, dass das verboten ist, scheint aber ein Defekt zu sein. Denn dieses func_refref kann weder dazu benutzt werden, einen Zeiger auf eine Funktion zu bilden, noch die Funktion selbst aufzurufen (beides setzt ein Funktions-lvalue voraus).
    Entweder müssen die entsprechenden Abschnitte in 4.3 und 5.2.2 geändert werden, oder dieses Konstrukt wird verboten oder als lvalue-Referenz intepretiert.
    Evtl. steht aber schon irgendwo etwas dazu.

    Funktion-rvalues entstehen traditionell nur in der Form gebundener Memberfunktionen, in

    struct { void foo(); } bar;
    bar.foo();
    

    ist

    bar.foo
    

    ein Funktions-rvalue (in C++03).



  • mgaeckler schrieb:

    Klar, nur wollte jemand ein einigermassen sinnvolles Bespiel.

    Eben - in C++ ist dein Beispiel nicht sinnvoll 😉



  • btw. ich muss hier mal einen Vorposter korrigieren:

    GetProcAddress gibt einen Funktionszeiger zurück, nämlich "void (*)(void)"
    oder wie Microsoft es per typedef nennt "FARPROC".

    Lediglich dlsym weist den Defekt auf, einen void* zurückzugeben.

    Btw. bevorzugte Nutzung von Funktionszeigern sind Callbacks.
    Das trifft aber hauptsächlich im Zusammenhang mit C-Bibliotheken auf,
    da man in C++ eben eher auf Templates und Funktoren setzt.
    Ausnahme stellen hier DLL's dar, da man Templates nicht ohne größere Probleme exportieren kann.



  • anti-freak schrieb:

    ok, passt nicht ganz, aber hat jemand irgendwo nen gutes tut für solche funktionsspielchen?

    http://www.newty.de/fpt/index.html



  • DrakoXP schrieb:

    Lediglich dlsym weist den Defekt auf, einen void* zurückzugeben.

    Das ist kein Defekt, das ist absicht. Es ist laut Standard undefiniertes Verhalten, einen Funktionszeiger in einern Funktionszeiger eines anderen Typs umzucasten.


  • Mod

    DrakoXP schrieb:

    Lediglich dlsym weist den Defekt auf, einen void* zurückzugeben.

    Das ist kein Defekt per se, weil nicht jedes Symbol auf eine Funktion verweist. Sauberer wäre nat. eine zweite Funktion speziell für Funktionssymbole.

    314159265358979 schrieb:

    Es ist laut Standard undefiniertes Verhalten, einen Funktionszeiger in einern Funktionszeiger eines anderen Typs umzucasten.

    Unfug.



  • DrakoXP schrieb:

    btw. ich muss hier mal einen Vorposter korrigieren:

    GetProcAddress gibt einen Funktionszeiger zurück, nämlich "void (*)(void)"
    oder wie Microsoft es per typedef nennt "FARPROC".

    Du hast Recht! *staun*
    Wurde das in den letzten 10 Jahren mal geändert? :xmas2:
    (Aber ne, vermutlich hab ich das nicht so in Erinnerung, weil es irgendwann früher mal so war, sondern weil ich es mir einfach eingebildet habe *g*)



  • camper schrieb:

    314159265358979 schrieb:

    Es ist laut Standard undefiniertes Verhalten, einen Funktionszeiger in einern Funktionszeiger eines anderen Typs umzucasten.

    Unfug.

    Wo definiert der Standard denn das Verhalten?





  • Achso, reinterpret_cast.



  • Habe mir die vorherigen Posts nicht durchgesehen, aber ein boost::function-ptr scheint mir hier am Passendsten.


Anmelden zum Antworten