'Innere' Klasse ala Lambda-Funktion in C++11



  • Ne, er meint lokale Klassen (in einer Funktion definiert). Dass das gehen würde, hab ich mir früher auch immer gewünscht, wollt das sogar schonmal proposen. Aber es geht halt eben nicht. Und nun gibts ja sowieso Lambdas 🙂



  • dot schrieb:

    Ne, er meint lokale Klassen (in einer Funktion definiert). Dass das gehen würde, hab ich mir früher auch immer gewünscht, wollt das sogar schonmal proposen. Aber es geht halt eben nicht. Und nun gibts ja sowieso Lambdas 🙂

    Funktionslokale Klassen sollen nicht gehen? Klar gehen die. Bisher gabs ein paar Einschränkungen, von denen in C++11 aber auch viele fallen gelassen wurden...



  • pumuckl schrieb:

    dot schrieb:

    Ne, er meint lokale Klassen (in einer Funktion definiert). Dass das gehen würde, hab ich mir früher auch immer gewünscht, wollt das sogar schonmal proposen. Aber es geht halt eben nicht. Und nun gibts ja sowieso Lambdas 🙂

    Funktionslokale Klassen sollen nicht gehen? Klar gehen die.

    Hab ich auch nichts andres behauptet. Soweit ich das verstanden hab, gehts in dem Thread hier gehts um Closures, bzw. eben das automatische capturen von lokalen Variablen. Und sowas gibts für lokale Klassen afaik nicht 😉

    EDIT: Ok, mein letztes Posting war wohl ziemlich schlecht formuliert 🤡



  • Hacker schrieb:

    Kannst du mal ein Beispiel geben, wie du dir vorstellst das es funktionieren soll?

    Etwa so:

    struct Foo {
    	virtual void foo(int j) = 0;
    	virtual void bar() = 0;
    }
    
    int main(){
    	int c = 7;
    	foobar(3,[] : public Foo { void foo(int j){return j*c;} void bar(){return c;} } );
    }
    

    Bestimmt kollidiert die frei erfundene Syntax mit irgendwelchen real existierenden.



  • Also eigentlich eher sowas ^^

    class MyObject{
    public:
    	void init(){
    		xyz.registerListener([this] : public MyListener { void event(const Event& e){internalObject.bar();} } );
    	}
    
    private:
    	InternalObject internalObject;
    };
    

    Aber läuft ja quasi auf das gleiche hinaus...



  • Iiiih, du willst Java in C++.



  • 314159265358979 schrieb:

    Iiiih, du willst Java in C++.

    Bist du auch ein Gegner von Lambda-Funktionen?

    Ich möchte gerne aufwandsarm programmieren 😉



  • C++11 schrieb:

    314159265358979 schrieb:

    Iiiih, du willst Java in C++.

    Bist du auch ein Gegner von Lambda-Funktionen?

    Wer ist Gegner von Lambdas? Das sind meine Lieblinge (C++11 natürlich sowieso) 😃 😃



  • Da fehlt aber was - du übergibst eine Klasse als Parameter, du musst aber ein Objekt übergeben, d.h. da fehlt noch der Konstruktoraufruf, und dann wird die Syntax so allmählich echt hässlich, selbst wenn man per default alle Konstruktorargumente an einen Ctor der Basisklasse weitergibt.

    Davon abgesehen gibts dafür nur wenig Verwendung. Nehmen wir dein zweites Beispiel. RegisterListener erwartet ein Derivat einer Listenerklasse, bei dem die Methode event überladen worden ist. Warum die ganze Klasse überladen lassen, wenns nur um die eine Methode geht? Das geht doch viel generischer:

    class GenericListener 
      : public MyListener //vorausgesetzt man braucht die MyListener Basisklasse überhaupt noch
    {
      typedef std::function<void(Event const&)> Eventhandler;
      eventhandler eh;
    public:
      GenericListener(Eventhandler e) : eh(e) {}
      virtual void event(Event const& evt) //überladen
      { eh(evt); }
    };
    
    class MyObject{
    public:
        void init(){
            xyz.registerListener(
               GenericListener([this](Event const&){internalObject.bar();})
            );
        }
    
    private:
        InternalObject internalObject;
    };
    

    Mit C++0x wirds in vielen Fällen nicht mehr darum gehen, irgendwelche Interfaces/abstrakten Klassen zu implementieren, stattdessen wirds deutlich generischer zugehen und für die zu implementierenden Interfaces werden Funktionsobjekte erwartet statt ganzer Klassen.

    der Aufruf von xyz.registerListener wird kein MyListener-Objekt mehr erwarten, sondern nurnoch ein std::function Objekt für den Event-Callback. Zum Beispiel wird das Observer-Pattern nicht mehr aus Observer und Observable bestehen, weil dank Lambdas JEDER zum Observer werden kann - man muss nurnoch per Einzeiler das passende Funktionsobjekt in den Pool des Observable stellen.



  • C++11 schrieb:

    Bist du auch ein Gegner von Lambda-Funktionen?

    Ich möchte gerne aufwandsarm programmieren 😉

    Nö, bin ich nicht. Im Gegenteil, Lambdas sind super sexy. Aber dein Ansatz ist zu Java-like, als dass man ihn unterstützen sollte. Und Aufwandsarm ist er ebenfalls nicht.


Anmelden zum Antworten