Mera om lambda

Som vi såg i exemplet med att beräkna summan kunde vi i lambdauttrycket binda en variabel från den omgivning där lambdat definierades, sum. Detta kallas också för en closure. Det är ju bra, att det har ett fint namn, men kan vi använda det på fler sätt?

En möjlighet är att binda till värdet av en variabel. I exemplet med summan var bindningen till en referens till variabeln sum så att vi kunde uppdatera summan från lambdauttrycket. Om vi i stället bara vill ha värdet av en variabel vid tillfället som lambdat skapades så binder vi just bara till värdet. Så här ser det ut:

[var] (... // capture variable var by value
[=] (...   // capture all variables by value
int divBy = 2;
auto divBy2 = [divBy] (int x) { return x / divBy; };

divBy = 4;
auto divBy4 = [divBy] (int x) { return x / divBy; };

assert(4 == divBy2(8));
assert(2 == divBy4(8));

Just! Det första lambdat dividerar med 2 och den andra med 4. Allt detta på grund av att divBy bands till värdet då lambdat skapades och inte till värdet då lambdat användes.

Vi kan till och med binda this. På det sättet kan man få tillgång till och anropa medlemmar i den klass där lambdat skapades. Vi skapar en klass Name (här använder vi struct för att göra exemplet lite kortare.)

struct Name 
{
   string name;
   void me() { cout << "I'm: " << name << endl; }
   function<void()> callMe() { return [&]() { me(); }; }
};

Den första medlemsfunktionen är lätt att förstå. Den skriver ut namnet på objektet.

Den andra medlemmen, callMe, kräver kanske lite mer förklaring. För det första introducerar den std::function. Här får vi nöja oss med att den deklarerar en typ som kan anropas med en parameter och med returtypen void. För det andra så returnerar den ett lambda som binder alla medlemmar i klassen Name och anropar medlemmen me.

När man använder det kan det se ut så här:

Name al {"Al"};
auto gl = al.callMe();
gl();    // Prints "I'm: Al"

Det blir som ett funktionsobjekt men skapas med mindre kod.

 

Publicerad i C/C++

Kategorier

WP to LinkedIn Auto Publish Powered By : XYZScripts.com