Lambda kifejezések C ++ nyelven

Lambda Expressions C



Miért a Lambda Expression?

Tekintsük a következő állítást:

intmyInt= 52;

Itt a myInt egy azonosító, egy érték. Az 52 szó szerinti, prvalue. Ma már lehetőség van egy függvény speciális kódolására és 52. pozícióba állítására. Az ilyen függvényt lambda kifejezésnek nevezzük. Vegye figyelembe a következő rövid programot is:







#befoglalni

segítségével névtérórák;

intfn(intkeresztül)

{

intválasz=keresztül+ 3;

Visszatérésválasz;

}


intfő-()

{

fn(5);



Visszatérés 0;

}

Ma már lehetőség van egy függvény speciális kódolására és az 5, az függvényhívás, az fn (5) argumentum pozíciójába helyezésére. Az ilyen függvényt lambda kifejezésnek nevezik. A lambda kifejezés (függvény) ebben a helyzetben egy érték.



Bármely literál, kivéve a karakterláncot, prvalue. A lambda kifejezés egy speciális funkció, amely szó szerint illeszkedik a kódba. Ez egy névtelen (névtelen) függvény. Ez a cikk elmagyarázza az új C ++ elsődleges kifejezést, az úgynevezett lambda kifejezést. A C ++ nyelv alapismerete elengedhetetlen a cikk megértéséhez.



Cikk tartalma

Lambda kifejezés illusztrációja

A következő programban egy függvény, amely egy lambda kifejezés, hozzá van rendelve egy változóhoz:





#befoglalni

segítségével névtérórák;

autofn= [](intálljon meg)

{

intválasz=álljon meg+ 3;

Visszatérésválasz;

};


intfő-()

{

autováltozó=fn(2);

költség <<változó<< ' n';


Visszatérés 0;

}

A kimenet:

5

A main () függvényen kívül van az fn változó. Típusa automata. Az automatikus ebben a helyzetben azt jelenti, hogy a tényleges típust, például int vagy float, a hozzárendelő operátor jobb operandusa határozza meg (=). A hozzárendelési operátor jobb oldalán egy lambda kifejezés található. A lambda kifejezés az előző visszatérési típus nélküli függvény. Vegye figyelembe a szögletes zárójel használatát és helyzetét, []. A függvény 5, int értéket ad vissza, amely meghatározza az fn típusát.



A main () függvényben a következő állítás található:

autováltozó=fn(2);

Ez azt jelenti, hogy az fn kívül a main () egy funkció azonosítója. Implicit paraméterei a lambda kifejezés paraméterei. A változó típusa automatikus.

Ne feledje, hogy a lambda kifejezés pontosvesszővel végződik, akárcsak az osztály vagy struktúra meghatározása, pontosvesszővel végződik.

A következő programban egy függvény, amely az 5 értékét visszaadó lambda kifejezés, egy argumentum egy másik függvényhez:

#befoglalni

segítségével névtérórák;

üresegyébfn(intno1,int (*ptr)(int))

{

intno2= (*ptr)(2);

költség <<no1<< '' <<no2<< ' n';

}


intfő-()

{

egyébfn(4,[](intálljon meg)

{

intválasz=álljon meg+ 3;

Visszatérésválasz;

});


Visszatérés 0;
}

A kimenet:

Négy öt

Itt két függvény létezik, a lambda kifejezés és a otherfn () függvény. A lambda kifejezés a mainfn () második argumentuma, amelyet a main () -ban hívnak. Vegye figyelembe, hogy a lambda függvény (kifejezés) ebben a hívásban nem végződik pontosvesszővel, mert itt ez egy argumentum (nem önálló függvény).

A lambda függvény paramétere a otherfn () függvény definíciójában egy függvény mutatója. A mutató neve, ptr. A ptr nevet a otherfn () definícióban a lambda függvény meghívására használják.

Az állítás,

intno2= (*ptr)(2);

A otherfn () definícióban 2 -es argumentummal hívja meg a lambda függvényt. A hívás visszatérési értéke, a (*ptr) (2) 'a lambda függvényből, a no2 -hez van hozzárendelve.

A fenti program azt is bemutatja, hogy a lambda függvény hogyan használható a C ++ visszahívási funkciósémában.

A Lambda Expression részei

A tipikus lambda függvény részei a következők:

[] () {}
  • [] a rögzítési záradék. Lehet benne elem.
  • () a paraméterlista.
  • {} a függvénytesthez tartozik. Ha a függvény egyedül áll, akkor pontosvesszővel kell befejeződnie.

Rögzíti

A lambda függvénydefiníció hozzárendelhető egy változóhoz, vagy argumentumként használható egy másik függvényhíváshoz. Az ilyen függvényhívás definíciójának paraméterként, mutatónak kell lennie egy függvényre, amely megfelel a lambda függvény definíciójának.

A lambda függvény definíciója eltér a normál függvénydefiníciótól. A globális hatókör változójához rendelhető; ez a változóhoz rendelt függvény egy másik függvényen belül is kódolható. Globális hatókör -változóhoz rendelve a törzs más változókat is láthat a globális hatókörben. Ha egy normál függvénydefiníción belüli változóhoz rendelik, annak törzse csak a rögzítési záradék segítségével láthatja a függvény hatókörének többi változóját, [].

A rögzítési záradék [], más néven lambda-bevezető, lehetővé teszi a változók küldését a környező (függvény) hatókörből a lambda kifejezés funkciótestébe. A lambda kifejezés függvénytörzse állítólag rögzíti a változót, amikor megkapja az objektumot. A rögzítési záradék [] nélkül nem lehet változót küldeni a környező hatókörből a lambda kifejezés funkciótestébe. A következő program ezt szemlélteti, a fő () függvénykörrel, mint a környező hatókörrel:

#befoglalni

segítségével névtérórák;

intfő-()

{

intid= 5;


autofn= [id]()

{

költség <<id<< ' n';

};

fn();


Visszatérés 0;

}

A kimenet az 5 . A név, id nélkül a [] belsejében a lambda kifejezés nem látta volna a main () függvény hatókörének változó azonosítóját.

Rögzítés hivatkozással

A rögzítési záradék fenti példa szerinti használata érték szerinti rögzítés (lásd az alábbi részleteket). A referenciaként történő rögzítés során a változó helyét (tárolását), például a fenti azonosítót, a környező hatókörben elérhetővé teszik a lambda függvénytestben. Tehát a lambda függvénytestben lévő változó értékének megváltoztatása megváltoztatja ugyanazon változó értékét a környező hatókörben. A rögzítési záradékban megismételt minden változót az ampersand (&) előzi meg ennek eléréséhez. Az alábbi program ezt szemlélteti:

#befoglalni

segítségével névtérórák;

intfő-()

{

intid= 5; úszóft= 2.3; charch= 'NAK NEK';

autofn= [&azonosító,&ft,&ch]()

{

id= 6;ft= 3.4;ch= 'B';

};

fn();

költség <<id<< ',' <<ft<< ',' <<ch<< ' n';

Visszatérés 0;

}

A kimenet:

6, 3,4, B.

Annak megerősítése, hogy a lambda kifejezés függvénytörzsében található változónevek ugyanazokra a változókra vonatkoznak a lambda kifejezésen kívül.

Érték szerinti rögzítés

Az érték szerinti rögzítés során a lambda függvénytestben elérhetővé válik a változó helyének másolata, a környező hatókör. Bár a lambda függvénytestben lévő változó másolat, értéke a testen belül jelenleg nem módosítható. Az érték szerinti rögzítés elérése érdekében a rögzítési záradékban megismételt minden változót nem előzi meg semmi. Az alábbi program ezt szemlélteti:

#befoglalni

segítségével névtérórák;

intfő-()

{

intid= 5; úszóft= 2.3; charch= 'NAK NEK';

autofn= [id, ft, ch]()

{

// id = 6; ft = 3,4; ch = 'B';

költség <<id<< ',' <<ft<< ',' <<ch<< ' n';

};

fn();

id= 6;ft= 3.4;ch= 'B';

költség <<id<< ',' <<ft<< ',' <<ch<< ' n';

Visszatérés 0;

}

A kimenet:

5, 2.3, A.

6, 3,4, B.

Ha a megjegyzésjelző eltávolításra kerül, a program nem fordítja le. A fordító hibaüzenetet ad ki, miszerint a függvénytest lambda kifejezés definíciójában szereplő változók nem módosíthatók. Bár a változók nem módosíthatók a lambda függvényen belül, a lambda függvényen kívül is módosíthatók, ahogy a fenti program kimenete is mutatja.

Rögzítés keverése

A referencia alapján történő rögzítés és az érték szerinti rögzítés keverhető, ahogy az alábbi program mutatja:

#befoglalni

segítségével névtérórák;

intfő-()

{

intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;


autofn= [id, ft,&ch,&bl]()

{

ch= 'B';bl= hamis;

költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


Visszatérés 0;

}

A kimenet:

5, 2,3, B, 0

Ha minden rögzítésre került, hivatkozás:

Ha az összes rögzítendő változót hivatkozás rögzíti, akkor csak egy & elegendő lesz a rögzítési záradékban. Az alábbi program ezt szemlélteti:

#befoglalni

segítségével névtérórák;

intfő-()

{

intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;


autofn= [&]()

{

id= 6;ft= 3.4;ch= 'B';bl= hamis;

};

fn();

költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';


Visszatérés 0;

}

A kimenet:

6, 3,4, B, 0

Ha egyes változókat referenciával, másokat értékkel kell rögzíteni, akkor az egyik & az összes hivatkozást reprezentálja, a többit pedig nem előzi meg semmi, ahogy az alábbi program mutatja:

segítségével névtérórák;

intfő-()

{

intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;


autofn= [&, id, ft]()

{

ch= 'B';bl= hamis;

költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


Visszatérés 0;

}

A kimenet:

5, 2,3, B, 0

Ne feledje, hogy az & önmagában (azaz, és az azonosító után nem) kell lennie a rögzítési záradék első karakterének.

Ha minden rögzítve van, érték szerint:

Ha az összes rögzítendő változót érték szerint kell rögzíteni, akkor csak egy = elegendő a rögzítési záradékban. Az alábbi program ezt szemlélteti:

#befoglalni

segítségével névtérórák;

intfő-()
{

intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;


autofn= [=]()

{

költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


Visszatérés 0;


}

A kimenet:

5, 2.3, A, 1

jegyzet : = jelenleg csak olvasható.

Ha egyes változókat értékkel, másokat pedig hivatkozással kell rögzíteni, akkor az egyik = az összes írásvédett másolt változót reprezentálja, a többi pedig & -et, mint a következő program mutatja:

#befoglalni

segítségével névtérórák;

intfő-()

{

intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;


autofn= [=,&ch,&bl]()

{

ch= 'B';bl= hamis;

költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


Visszatérés 0;

}

A kimenet:

5, 2,3, B, 0

Ne feledje, hogy a = egyedül kell, hogy legyen a rögzítési záradék első karaktere.

Klasszikus visszahívási funkció séma Lambda kifejezéssel

A következő program bemutatja, hogyan lehet elvégezni a klasszikus visszahívási függvénysémát a lambda kifejezéssel:

#befoglalni

segítségével névtérórák;

char *Kimenet;


autocba= [](charki[])

{

Kimenet=ki;

};



üresmainFunc(charbemenet[],üres (*számára)(char[]))

{

(*számára)(bemenet);

költség<<'a fő funkcióhoz'<<' n';

}


üresfn()

{

költség<<'Most'<<' n';

}


intfő-()

{

charbemenet[] = 'visszahívási funkcióhoz';

mainFunc(bemenet, cba);

fn();

költség<<Kimenet<<' n';



Visszatérés 0;

}

A kimenet:

fő funkciójához

Most

visszahívási funkcióhoz

Emlékezzünk vissza, hogy amikor egy lambda kifejezés definíciót hozzárendelünk egy változóhoz a globális hatókörben, annak függvényteste láthatja a globális változókat a rögzítési záradék alkalmazása nélkül.

A trailing-return típus

A lambda kifejezés visszatérési típusa automatikus, vagyis a fordító határozza meg a visszatérési típust a visszatérési kifejezésből (ha van). Ha a programozó valóban meg akarja adni a visszatérési típust, akkor ezt a következő program szerint fogja tenni:

#befoglalni

segítségével névtérórák;

autofn= [](intálljon meg) -> int

{

intválasz=álljon meg+ 3;

Visszatérésválasz;

};


intfő-()

{

autováltozó=fn(2);

költség <<változó<< ' n';


Visszatérés 0;

}

A kimenet 5. A paraméterlista után a nyíl operátor beírásra kerül. Ezt követi a visszatérési típus (ebben az esetben az int).

Bezárás

Tekintsük a következő kódrészletet:

strukCla

{

intid= 5;

charch= 'nak nek';

}obj1, obj2;

Itt Cla a struktura osztály neve. Az Obj1 és az obj2 két olyan objektum, amelyek a struktura osztályból lesznek példányosítva. A Lambda kifejezés hasonló a megvalósításban. A lambda függvény definíció egyfajta osztály. Amikor a lambda függvényt meghívjuk (meghívjuk), egy objektum a példányából származik. Ezt az objektumot zárásnak nevezik. A zárás az, ami elvégzi a lambdától elvárt munkát.

Azonban a lambda kifejezésnek a fenti struktúrához hasonló kódolása esetén az obj1 és az obj2 helyére a megfelelő paraméterek argumentumai lépnek. Az alábbi program ezt szemlélteti:

#befoglalni

segítségével névtérórák;

autofn= [](intparam1,intparam2)

{

intválasz=param1+param2;

Visszatérésválasz;

} (2,3);


intfő-()

{

autoahol=fn;

költség <<ahol<< ' n';


Visszatérés 0;

}

A kimenet 5. Az argumentumok 2 és 3 zárójelben vannak. Vegye figyelembe, hogy a lambda kifejezés függvényhívása, az fn, nem fogad el érveket, mivel az argumentumok már a lambda függvénydefiníció végén vannak kódolva.

Következtetés

A lambda kifejezés névtelen függvény. Két részből áll: osztály és objektum. Meghatározása egyfajta osztály. A kifejezés meghívásakor egy objektum keletkezik a definícióból. Ezt az objektumot zárásnak nevezik. A zárás az, ami elvégzi a lambdától elvárt munkát.

Ahhoz, hogy a lambda kifejezés változót kapjon egy külső függvény hatókörből, nem üres rögzítési záradékra van szüksége a függvénytestébe.