C++11: LambdaFunktionen



  • Warum geht folgendes nicht?

    class T
    {
    int i;
    void foo()
    {
     .... [i](int j) {return i == j;} ...
    }
    };
    

    Das Problem scheint zu sein, dass ich auf eine Membervariable zugreife: VC++ meldet a lambda capture variable must be from an enclosing function scope
    requires the compiler to capture 'this' but the current default capture mode does not allow it



  • Geht es denn wenn du i durch this->i ersetzt oder dir eine lokale Variable in der Funktion anlegst, also int i_temp=i und dann i durch i_temp ersetzt?



  • "der dir eine lokale Variable in der Funktion anlegst, also int i_temp=i und dann i durch i_temp ersetzt?" -> Dann geht es, ist aber nicht elegant.



  • Capture this statt i (möglicherweise musst du dann mit this->i darauf zugreifen).



  • Lies dir dazu mal den Abschnitt "capture clause" auf Lambda Expression Syntax durch und schau dir mal das entsprechende Beispiel auf Examples of Lambda Expressions an.

    Grüsse



  • Man darf nur lokale Variablen in der Capture-Clause benennen und this. i ist keine lokale Variable. i ist nur die Kurzform von this->i. Verwendest Du = oder `this` in der Capture-Clause, wird der Wert des this-Zeigers kopiert. Um eine Kopie von i im Lambda-Objekt zu speichern, gibt es folgenden Workaround:

    auto& z = i;
    [z](int j) {return z==j;};
    

    Mit der ersten Zeile wird z als "lokales Synonym" zu i definiert. Das darf in der Capture-Clause auftauchen. Das z im Funktionskörper des Lambda-Ausdrucks bezieht sich auf eine Kopie. Mir gefällt das auch nicht, dass man einen Umweg über eine lokale Referenz machen muss. Aber wir können es jetzt nicht mehr ändern. Zumindest nicht bis zur nächsten C++-Version. Ich kann mir gut vorstellen, dass in der nächsten C++ Version ("C++1y") die Capture-Clause flexibler wird und man in dieser Situation nicht diese lästige lokale Referenz einfügen muss und dafür direkt i benennen kann. Hoffentlich bekommen wir dann neben "capture by copy" und "capture by reference" auch ein "capture by move".


Anmelden zum Antworten