Funktion als Rückgabetyp



  • 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.



  • Bitte wie?
    boost::function ist ein Funktor. Den man üblicherweise by-value übergibt.

    Hier geht's um Funktionszeiger bzw. "native" Funktionstypen.

    Wo genau soll jetzt also ein "boost::function-ptr" passend sein, und was verstehst du überhaupt darunter.


Anmelden zum Antworten