Adressübergabe einer Memberfunktion



  • Lambda zu Fuß (ungetestet!):

    int message::connect_member(person *inst, void(person::*func)()){
        struct Lambda
        {
           person *inst;
           void(person::*func)();
           void operator()() const { (inst->*func)(); }
           Lambda(person *inst, void(person::*func)()) : inst(inst), func(func){}
        };
    
        slots_.insert(std::make_pair(++current_id_, Lambda(inst, func) ));
        return current_id_;
    }
    

    Ansonsten erklärt jedes aktuelle C++ Buch Lambdas.



  • Hallo Manni,
    ich hoffe ein letztes Mal.
    Das mit der Lambda-Funktion ist aktuell für mich noch zu "hoch". Das lassen wir mal.
    Ich will ja nur verstehen wie man die Adressen von Memberfunktionen speichert und wieder darauf zugreifen kann.
    Du schreibst weiter oben "
    "... oder connect_member direkt eine std::function übergeben."

    Ich brauche doch immer das Objekt selbst. Der Zeiger auf dessen Memberfunktion genügt doch nicht. Oder doch ? 🙄

    Ich habe mal die connect_member(...) so wie du es vorgeschlagen hast umgebaut.
    Mir ist unklar wie der Aufruf von connect_member(...) bzw. die Adressübergabe erfolgt.
    Den Code habe ich etwas abgeändert. "Person" entfällt, dafür gibt es einen "Sender" und "Receiver".
    In der Zeile 38 mache ich was falsch!

    //--- message.cpp ---
    int message::connect_member(std::function<void()>& slot){
    
        slots_.insert(std::make_pair(++current_id_, slot));
        return current_id_;
    }
    
    //-- receiver.h ---
    class receiver
    {
    public:
        receiver();
        message _say;
    
        int listen();
    };
    
    //--- sender.h ---
    class sender
    {
    public:
        sender();
        message _say;
    };
    
    //--- main ---
    int main()
    {
        sender bob;
        receiver alice;
    
        typedef int (receiver::*rcvFunc)();
        receiver *pw = &alice;
        rcvFunc memberFunc = &receiver::listen;
        //(pw->*memberFunc)();
    
        int id = bob._say.connect_member(memberFunc); // ???????
    
        return 0;
    }
    


  • schnebe schrieb:

    Das mit der Lambda-Funktion ist aktuell für mich noch zu "hoch". Das lassen wir mal.

    Das ist mit Sciherheit einfacher als die hampelei mit Funktionspointern.

    schnebe schrieb:

    Ich will ja nur verstehen wie man die Adressen von Memberfunktionen speichert und wieder darauf zugreifen kann.
    ...
    Ich brauche doch immer das Objekt selbst. Der Zeiger auf dessen Memberfunktion genügt doch nicht. Oder doch ? 🙄

    Ja, wenn du mit Funktionspointern auf nicht statische Member rumhampelst, brauchst du auch ein Objekt dazu.

    schnebe schrieb:

    Du schreibst weiter oben "
    "... oder connect_member direkt eine std::function übergeben."

    Ja, und dann verwendest du ein Lambda ohne Pointerhampelei (ungetestet!):

    int main()
    {
        sender bob;
        receiver alice;
    
        auto listen = [&](){ alice.listen(); };
    
        int id = bob._say.connect_member( listen ); 
    
    ...
    


  • Leider kommt noch eine Fehlermeldung:

    ..\sender_receiver\main.cpp: In function 'int main()':
    ..\sender_receiver\main.cpp:19:44: error: no matching function for call to 'message::connect_member(main()::<lambda()>&)'
    int id = bob._say.connect_member(listen);
    ^
    In file included from ..\sender_receiver\sender.h:4:0,
    from ..\sender_receiver\main.cpp:2:
    ..\sender_receiver\message.h:11:9: note: candidate: int message::connect_member(std::function<void()>&)
    int connect_member(std::function<void()>& slot);
    ^
    ..\sender_receiver\message.h:11:9: note: no known conversion for argument 1 from 'main()::<lambda()>' to 'std::function<void()>&'
    ..\sender_receiver\main.cpp:19:9: warning: unused variable 'id' [-Wunused-variable]
    int id = bob._say.connect_member(listen);

    Wenns tut dann laß ich dich in Ruhe :p



  • Hier:

    int message::connect_member(std::function<void()>& slot){
    

    Warum hast du hier eine (non-const) Referenz auf eine std::function?



  • Warum ist eine const Ref. auf std:function erforderlch ?

    Wie müsste diese schreiben?

    // message.h
    int connect_member(std::function<void()> const& slot);
    
    // message.cpp
    int message::connect_member(std::function<void()> const& slot)
    {
    slots_.insert(std::make_pair(++current_id_, slot));
        return current_id_;
    }
    


  • Der Rückgabetyp paßt nicht überein: void <-> int



  • ok der Rückgabetyp war falsch - habe nun

    void message::listen() definiert
    

    leider kommt immer noch folgende Fehlermeldung:
    ..\sender_receiver\main.cpp: In function 'int main()':
    ..\sender_receiver\main.cpp:13:44: error: no matching function for call to 'message::connect_member(main()::<lambda()>&)'
    int id = bob._say.connect_member(listen);
    ^
    In file included from ..\sender_receiver\sender.h:4:0,
    from ..\sender_receiver\main.cpp:2:
    ..\sender_receiver\message.h:13:9: note: candidate: int message::connect_member(std::function<void()>&)
    int connect_member(std::function<void()> & slot);
    ^
    DIESE FEHLERMELDUNG DÜRFTE AM AUSSAGEFRÄFTIGSTEN SEIN:
    ..\sender_receiver\message.h:13:9: note: no known conversion for argument 1 from 'main()::<lambda()>' to 'std::function<void()>&'

    //message.cpp
    int message::connect_member(std::function<void()> & slot){
    
        slots_.insert(std::make_pair(++current_id_, slot));
        return current_id_;
    }
    
    // receiver.h
    class receiver
    {
    public:
        receiver();
        message _say;
        void listen();
    };
    
    //main
    int main()
    {
        sender bob;
        receiver alice;
    
        auto listen = [&](){ alice.listen(); };
        int id = bob._say.connect_member(listen);
    
        return id;
    }
    


  • int message::connect_member(std::function<void()>  slot)
    


  • Nun kommt eine Templatefehlermeldung !?!?

    ..\sender_receiver\message.cpp:9:45: error: template argument 1 is invalid
    int message::connect_member(std::function<()> slot){


  • Mod

    Suchspiel: Finde den Unterschied!

    schnebe schrieb:

    int message::connect_member(std::function<()> slot)
    

    manni66 schrieb:

    int message::connect_member(std::function<void()>  slot)
    


  • Danke Manni - tut!

    Ich nehme an daß der &-Operator in der "connect_member" entfällt , da durch die Bindung [&] bereits eine Referenz zurück gegeben wird.



  • schnebe schrieb:

    Ich nehme an daß der &-Operator in der "connect_member" entfällt , da durch die Bindung [&] bereits eine Referenz zurück gegeben wird.

    Solltest du das & an std::function meinen: Nein! Eine std::function kann ein Lambda entgegennehmen, ein Lambda ist aber keine std::function.



  • Ok!
    Bin mittlerweile auch bei der Lambdafunktion schlauer geworden durch gute Beispiele. Ich muß es jetzt "nur" für meinen Anwendungsfall umsetzen.

    Nochmal Danke an alle!


Anmelden zum Antworten