C ++

Lambda kifejezések C ++ nyelven

Lambda kifejezések C ++ nyelven

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:

#include
né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:

#include
né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:

    5

A 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:

#include
né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 5

Ké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:

#include
né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:

#include
né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, B

Megerő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:

#include
né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, A
6, 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:

#include
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, & bl] ()

ch = 'B'; bl = hamis;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
visszatér 0;

A kimenet:

    5, 2.3, B, 0

Ha 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:

#include
né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, 0

Ha 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, 0

Ne 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:

#include
né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, 1

jegyzet: = 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:

#include
né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, 0

Ne 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:

#include
né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<visszatér 0;

A kimenet:

fő funkcióra
Most
a visszahívási funkcióhoz

Emlékezzünk arra, hogy amikor a lambda kifejezés definícióját egy változóhoz rendeljük a globális hatókörben, akkor annak függvényteste a globális változókat láthatja anélkül, hogy alkalmazná a rögzítési záradékot.

Utána visszatérő típus

A lambda kifejezés visszatérési típusa automatikus, vagyis a fordító a visszatérési kifejezést a visszatérési kifejezés alapján határozza meg (ha van ilyen). Ha a programozó valóban meg akarja jelölni a visszatérési típust, akkor a következő program szerint fogja megtenni:

#include
névtér használata std;
auto fn = [] (int param) -> int

int válasz = param + 3;
válasz válasz;
;
int main ()

auto változó = fn (2);
cout << variab << '\n';
visszatér 0;

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

Bezárás

Vegye figyelembe a következő kódszegmenst:

struct Cla

int id = 5;
char ch = 'a';
obj1, obj2;

Itt Cla a struktúra osztály neve.  Az Obj1 és az Obj2 két objektum, amelyet a struct osztályból példányosítunk. A lambda kifejezés végrehajtása hasonló. A lambda függvény meghatározása egyfajta osztály. Amikor a lambda függvényt meghívják (meghívják), akkor egy objektum példányos lesz a definíciójából. Ezt az objektumot bezárásnak nevezzük. A lezárás végzi azt a munkát, amelyet a lambda várhatóan elvégez.

Ugyanakkor a lambda kifejezés kódolásához hasonlóan a fenti struktúrához az obj1 és az obj2 helyébe a megfelelő paraméterek argumentumai lépnek. A következő program ezt szemlélteti:

#include
névtér használata std;
auto fn = [] (int param1, int param2)

int válasz = param1 + param2;
válasz válasz;
(2, 3);
int main ()

auto var = fn;
cout << var << '\n';
visszatér 0;

A kimenet 5. Az érvek 2 és 3 zárójelben vannak. Vegye figyelembe, hogy a lambda kifejezés függvényhívása, az fn, nem tartalmaz argumentumot, mivel az argumentumokat már kódolták a lambda függvény definíciójának végén.

Következtetés

A lambda kifejezés anonim függvény. Két részből áll: osztály és tárgy. Meghatározása egyfajta osztály. A kifejezés meghívásakor egy objektum képződik a definícióból. Ezt az objektumot bezárásnak nevezzük. A lezárás végzi azt a munkát, amelyet a lambda várhatóan elvégez.

Ahhoz, hogy a lambda kifejezés egy változót egy külső függvény hatóköréből fogadjon, egy nem üres elfogási záradékra van szüksége a függvénytörzsében.

Microsoft Sculpt Touch vezeték nélküli egér áttekintés
Nemrég olvastam a Microsoft Sculpt Touch vezeték nélküli egér és úgy döntött, hogy megveszi. Egy ideig használat után úgy döntöttem, hogy megosztom ve...
AppyMouse képernyős Trackpad és egérmutató a Windows táblagépekhez
A táblagép-felhasználók gyakran hiányolják az egérmutatót, különösen akkor, ha szokták használni a laptopokat. Az érintőképernyős okostelefonok és táb...
Az egér középső gombja nem működik a Windows 10 rendszerben
A középső egérgomb segít átgörgetni a hosszú weboldalakat és a sok adatot tartalmazó képernyőket. Ha ez leáll, akkor a billentyűzet segítségével görge...