Miért a Lambda Expression??
Vegye figyelembe a következő állítást:
int myInt = 52;Itt a myInt egy azonosító, egy érték. Az 52 szó szerinti, prvalue. Ma lehetőség van egy funkció speciális kódolására és 52-es helyzetbe helyezésére. Az ilyen funkciót lambda kifejezésnek nevezzük. Fontolja meg a következő rövid programot is:
#includenévtér használata std;
int fn (int par)
int válasz = par + 3;
válasz válasz;
int main ()
fn (5);
visszatér 0;
Ma lehetőség van egy függvény speciális kódolására és az fn (5) függvényhívás 5 argumentumának helyére. Az ilyen funkciót lambda kifejezésnek nevezzük. Az ebben a helyzetben lévő lambda kifejezés (függvény) előérték.
A literál karakterlánc kivételével minden literál értéke prvalue. A lambda kifejezés egy speciális függvényterv, amely betűként 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 cikk megértéséhez elengedhetetlen a C ++ nyelven írt alapismeretek.
A cikk tartalma
- A lambda kifejezés illusztrációja
- A Lambda Expression részei
- Rögzítések
- Klasszikus visszahívási funkció séma Lambda kifejezéssel
- Utána visszatérő típus
- Bezárás
- Következtetés
A lambda kifejezés illusztrációja
A következő programban egy függvényt, amely egy lambda kifejezés, egy változóhoz rendelünk:
#includenévtér használata std;
auto fn = [] (int param)
int válasz = param + 3;
válasz válasz;
;
int main ()
auto változó = fn (2);
cout << variab << '\n';
visszatér 0;
A kimenet:
5A main () függvényen kívül található az fn változó. Típusa automatikus. Az automatikus ebben a helyzetben azt jelenti, hogy a tényleges típust, például az int vagy az úszót, a hozzárendelés operátorának megfelelő operandusza határozza meg (=). A hozzárendelés 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ójelek használatát és helyzetét, []. A függvény 5-öt ad vissza, int, amely meghatározza az fn típusát.
A main () függvényben van egy állítás:
auto változó = fn (2);Ez azt jelenti, hogy az fn a main () kívül található, mint egy függvény azonosítója. Implicit paraméterei megegyeznek a lambda expresszióval. A változó típusa auto.
Vegye figyelembe, hogy a lambda kifejezés pontosvesszővel végződik, akárcsak az osztály vagy a struktúra definíciója, pontosvesszővel végződik.
A következő programban egy függvény, amely az 5 értékét visszaadó lambda kifejezés, egy másik függvény argumentuma:
#includenévtér használata std;
void otherfn (int no1, int (* ptr) (int))
int no2 = (* ptr) (2);
cout << no1 << " << no2 << '\n';
int main ()
otherfn (4, [] (int param)
int válasz = param + 3;
válasz válasz;
);
visszatér 0;
A kimenet:
4 5Két funkció van itt, a lambda kifejezés és a másikfn () függvény. A lambda kifejezés a otherfn () második argumentuma, amelyet main (). Ne feledje, hogy a lambda függvény (kifejezés) nem végződik pontosvesszővel ebben a hívásban, mert itt ez egy argumentum (nem önálló függvény).
A lambda függvény paramétere a másikfn () függvény definíciójában egy függvény mutatója. A mutató neve, ptr. A ptr nevet a másikfn () definícióban használják a lambda függvény meghívására.
Az állítás,
int no2 = (* ptr) (2);A másikfn () definícióban a 2 argumentummal hívja meg a lambda függvényt. A hívás visszatérési értéke, a lambda függvényből "(* ptr) (2)", a no2-hez van rendelve.
A fenti program azt is bemutatja, hogy a lambda függvény hogyan használható a C ++ visszahívási függvény 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. Lehetnek elemei.
- () a paraméterlistára vonatkozik.
- A a függvénytestre vonatkozik. Ha a függvény egyedül áll, akkor pontosvesszővel kell végződnie.
Rögzítések
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 egy mutatót kell tartalmaznia 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ény definíciójától. Hozzárendelhető egy változóhoz a globális hatókörben; ezt a függvényhez hozzárendelt változót egy másik függvénybe is be lehet kódolni. Globális hatókörű változóhoz rendelve a test más globális hatókörű változásokat is láthat. Ha egy normál függvénydefiníción belüli változóhoz rendeljük, annak teste csak a rögzítési záradék segítségével láthatja a függvény hatókörében lévő egyéb változóit.
A rögzítési záradék [], más néven lambda-bevezetõ, lehetõvé teszi a változók elküldését a környezõ (függvény) hatókörbõl a lambda kifejezés függvénytörzsébe. Állítólag a lambda kifejezés függvényteste elfogja a változót, amikor megkapja az objektumot. Az elfogási záradék [] nélkül egy változó nem küldhető el a környező hatókörből a lambda kifejezés függvénytörzsébe. A következő program ezt szemlélteti a main () függvény hatókörével, mint a környező hatókörrel:
#includenévtér használata std;
int main ()
int id = 5;
auto fn = [id] ()
cout << id << '\n';
;
fn ();
visszatér 0;
A kimenet az 5. Név, id, belül [] nélkül a lambda kifejezés nem látta volna a main () függvény hatókörének változó id-jét.
Rögzítés referenciával
A rögzítési záradék fenti példája az érték szerinti rögzítést jelenti (lásd alább). Hivatkozással történő rögzítéskor a változó helye (tárolása), pl.g., A fenti id, a környező hatókörű, elérhetővé válik a lambda funkciótest belsejében. Tehát a lambda függvénytesten belüli 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ése érdekében. A következő program ezt szemlélteti:
#includenévtér használata std;
int main ()
int id = 5; úszó ft = 2.3; char ch = 'A';
auto fn = [& id, & ft, & ch] ()
id = 6; ft = 3.4; ch = 'B';
;
fn ();
cout << id << ", " << ft << ", " << ch << '\n';
visszatér 0;
A kimenet:
6, 3.4, BMegerősítve, hogy a lambda kifejezés függvénytestében lévő változók neve ugyanazokra a változókra vonatkozik a lambda kifejezésen kívül.
Érték alapján megragadni
Érték alapján történő rögzítéskor a változó helyének és a környező hatókörnek a másolata elérhetővé válik a lambda függvénytesten belül. Habár a lambda függvénytesten belüli változó másolat, értéke a testen belül mostanáig nem változtatható meg. 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. A következő program ezt szemlélteti:
#includenévtér használata std;
int main ()
int id = 5; úszó ft = 2.3; char ch = 'A';
auto fn = [id, ft, ch] ()
id = 6; ft = 3.4; ch = 'B';
cout << id << ", " << ft << ", " << ch << '\n';
;
fn ();
id = 6; ft = 3.4; ch = 'B';
cout << id << ", " << ft << ", " << ch << '\n';
visszatér 0;
A kimenet:
5, 2.3, A6, 3.4, B
Ha eltávolítja a megjegyzés jelzőt, a program nem fordít. A fordító hibaüzenetet küld, miszerint a lambda kifejezés függvénytest definíciójában lévő változók nem változtathatók meg. Bár a változókat a lambda függvényen belül nem lehet megváltoztatni, a lambda függvényen kívül megváltoztathatók, amint a fenti program kimenete mutatja.
Felvételek keverése
A hivatkozással történő rögzítés és az érték szerinti rögzítés keverhető, amint azt a következő program mutatja:
#includenévtér használata std;
int main ()
int id = 5; úszó ft = 2.3; char ch = 'A'; bool bl = igaz;
auto fn = [id, ft, & ch, & bl] ()
ch = 'B'; bl = hamis;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
visszatér 0;
A kimenet:
5, 2.3, B, 0Ha az összes elfogott, hivatkozásként:
Ha az összes rögzítendő változó referenciával kerül rögzítésre, akkor a rögzítési záradékban csak egy és elegendő. A következő program ezt szemlélteti:
#includenévtér használata std;
int main ()
int id = 5; úszó ft = 2.3; char ch = 'A'; bool bl = igaz;
auto fn = [&] ()
id = 6; ft = 3.4; ch = 'B'; bl = hamis;
;
fn ();
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
visszatér 0;
A kimenet:
6, 3.4, B, 0Ha egyes változókat referenciával, másokat pedig értékkel kell rögzíteni, akkor az egyik & az összes referenciát képviseli, a többit pedig nem előzi meg semmi, amint azt a következő program mutatja:
névtér használata std;int main ()
int id = 5; úszó ft = 2.3; char ch = 'A'; bool bl = igaz;
auto fn = [&, id, ft] ()
ch = 'B'; bl = hamis;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
visszatér 0;
A kimenet:
5, 2.3, B, 0Ne feledje, hogy & egyedül (i.e., és utána nem szerepel azonosító) a rögzítési záradék első karakterének kell lennie.
Ha minden elfogott, érték szerint vannak:
Ha az összes rögzítendő változót értékkel kell rögzíteni, akkor a rögzítési záradékban csak egy = elegendő. A következő program ezt szemlélteti:
#includenévtér használata std;
int main ()
int id = 5; úszó ft = 2.3; char ch = 'A'; bool bl = igaz;
auto fn = [=] ()
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
visszatér 0;
A kimenet:
5, 2.3, A, 1jegyzet: = mostantól csak olvasható.
Ha néhány változót értékkel, másokat referenciával akarunk rögzíteni, akkor az egyik = az összes csak olvasható másolt változót képviseli, a többinek pedig mindegyiké lesz, és a következő program mutatja:
#includenévtér használata std;
int main ()
int id = 5; úszó ft = 2.3; char ch = 'A'; bool bl = igaz;
auto fn = [=, & ch, & bl] ()
ch = 'B'; bl = hamis;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
visszatér 0;
A kimenet:
5, 2.3, B, 0Ne feledje, hogy a = egyedül kell lennie az első karakternek a rögzítési záradékban.
Klasszikus visszahívási funkció séma Lambda kifejezéssel
A következő program bemutatja, hogyan lehet egy klasszikus visszahívási függvénysémát végrehajtani a lambda kifejezéssel:
#includenévtér használata std;
char * output;
auto cba = [] (char out [])
kimenet = ki;
;
void basicFunc (char bemenet [], void (* pt) (char []))
(* pt) (bemenet);
cout<<"for principal function"<<'\n';
void fn ()
cout<<"Now"<<'\n';
int main ()
char input [] = "a visszahívási funkcióhoz";
mainFunc (input, cba);
fn ();
cout<