C ++

Lambda izteiksmes C ++

Lambda izteiksmes C ++

Kāpēc Lambda izteiksme?

Apsveriet šādu apgalvojumu:

    int myInt = 52;

Šeit myInt ir identifikators, vērtība. 52 ir burtisks, prvalue. Šodien funkciju ir iespējams īpaši kodēt un ievietot 52 pozīcijā. Šādu funkciju sauc par lambda izteiksmi. Apsveriet arī šo īso programmu:

# iekļaut
izmantojot nosaukumvietu std;
int fn (int par)

int atbilde = par + 3;
atbilde uz atbildi;

int main ()

fn (5);
atgriešanās 0;

Šodien funkciju ir iespējams īpaši kodēt un ievietot funkcijas argumenta 5, funkcijas izsaukuma, fn (5) pozīcijā. Šādu funkciju sauc par lambda izteiksmi. Lambda izteiksme (funkcija) šajā pozīcijā ir sākotnējā vērtība.

Jebkurš literārs, izņemot virknes literālu, ir prvalue. Lambda izteiksme ir īpašs funkcijas dizains, kas derētu kā burtiskais kods. Tā ir anonīma (nenosaukta) funkcija. Šajā rakstā ir izskaidrota jaunā C ++ primārā izteiksme, ko sauc par lambda izteiksmi. Lai saprastu šo rakstu, ir nepieciešamas pamatzināšanas C ++ valodā.

Raksta saturs

  • Lambda izteiksmes ilustrācija
  • Lambda izteiksmes daļas
  • Tver
  • Klasiskās atzvanīšanas funkciju shēma ar Lambda izteiksmi
  • Aizmugures-atgriešanās tips
  • Slēgšana
  • Secinājums

Lambda izteiksmes ilustrācija

Šajā programmā mainīgajam tiek piešķirta funkcija, kas ir lambda izteiksme:

# iekļaut
izmantojot nosaukumvietu std;
auto fn = [] (int param)

int atbilde = param + 3;
atbilde uz atbildi;
;
int main ()

auto mainīgais = fn (2);
cout << variab << '\n';
atgriešanās 0;

Rezultāts ir:

    5

Ārpus galvenās () funkcijas ir mainīgais fn. Tās tips ir auto. Auto šajā situācijā nozīmē, ka faktisko tipu, piemēram, int vai float, nosaka piešķiršanas operatora pareizais operands (=). Piešķiršanas operatora labajā pusē ir lambda izteiksme. Lambda izteiksme ir funkcija bez iepriekšējā atgriešanās veida. Ievērojiet kvadrātiekavu izmantošanu un atrašanās vietu, []. Funkcija atgriež 5, int, kas noteiks fn tipu.

Funkcijā main () ir paziņojums:

    auto mainīgais = fn (2);

Tas nozīmē, ka fn ārpus main () nonāk kā funkcijas identifikators. Tās netiešie parametri ir lambda izteiksmes parametri. Mainīgā tips ir auto.

Ņemiet vērā, ka lambda izteiksme beidzas ar semikolu, tāpat kā klases vai struktūras definīcija, beidzas ar semikolu.

Šajā programmā funkcija, kas ir lambda izteiksme, kas atgriež vērtību 5, ir arguments citai funkcijai:

# iekļaut
izmantojot nosaukumvietu std;
anulēt otherfn (int no1, int (* ptr) (int))

int no2 = (* ptr) (2);
cout << no1 << " << no2 << '\n';

int main ()

otherfn (4, [] (int param)

int atbilde = param + 3;
atbilde uz atbildi;
);
atgriešanās 0;

Rezultāts ir:

    4 5

Šeit ir divas funkcijas, lambda izteiksme un otrafn () funkcija. Lambda izteiksme ir otrais arguments otherfn (), ko sauc par main (). Ņemiet vērā, ka lambda funkcija (izteiksme) šajā izsaukumā nebeidzas ar semikolu, jo šeit tas ir arguments (nevis atsevišķa funkcija).

Funkcijas lambda parametrs otherfn () funkcijas definīcijā ir rādītājs funkcijai. Rādītājam ir nosaukums, ptr. Nosaukums ptr tiek izmantots definīcijā otherfn (), lai izsauktu lambda funkciju.

Paziņojums,

    int no2 = (* ptr) (2);

Definīcijā otherfn () tā izsauc funkciju lambda ar argumentu 2. Zvana atgriešanās vērtība "(* ptr) (2)" no lambda funkcijas tiek piešķirta no2.

Iepriekš minētā programma arī parāda, kā lambda funkciju var izmantot C ++ atzvanīšanas funkciju shēmā.

Lambda izteiksmes daļas

Tipiskas lambda funkcijas daļas ir šādas:

    [] ()
  • [] ir uztveršanas klauzula. Tajā var būt preces.
  • () ir paredzēts parametru sarakstam.
  • ir paredzēts funkcijas ķermenim. Ja funkcija stāv atsevišķi, tad tai jābeidzas ar semikolu.

Tver

Funkcijas lambda definīciju var piešķirt mainīgajam vai izmantot kā argumentu citam funkcijas izsaukumam. Šāda funkcijas izsaukuma definīcijai kā parametram jābūt funkcijas rādītājam, kas atbilst lambda funkcijas definīcijai.

Lambda funkcijas definīcija atšķiras no parastās funkcijas definīcijas. To var piešķirt mainīgajam globālajā tvērumā; šo funkciju, kas piešķirta mainīgajam, var kodēt arī citas funkcijas iekšpusē. Kad tas tiek piešķirts globālās darbības mainīgajam, tā pamatteksts var redzēt citus mainīgos globālajā darbības jomā. Kad tas tiek piešķirts mainīgajam parastas funkcijas definīcijas ietvaros, tā pamatteksts var redzēt citus mainīgos lielumus tikai ar uztveršanas klauzulas palīdzību, [].

Uztveršanas klauzula [], kas pazīstama arī kā lambda ievada, ļauj mainīgos no apkārtējās (funkcijas) darbības jomas nosūtīt lambda izteiksmes funkcijas ķermenī. Tiek teikts, ka lambda izteiksmes funkcijas ķermenis uztver mainīgo, saņemot objektu. Bez uztveršanas klauzulas [] mainīgo nevar nosūtīt no apkārtējās darbības jomas uz lambda izteiksmes funkcijas ķermeni. Nākamā programma to ilustrē ar galveno () funkcijas darbības jomu kā apkārtējo:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5;
auto fn = [id] ()

cout << id << '\n';
;
fn ();
atgriešanās 0;

Rezultāts ir 5. Bez nosaukuma, id, iekšpusē [] lambda izteiksme nebūtu redzējusi main (main) funkcijas funkcijas main () funkciju.

Tveršana, izmantojot atsauci

Iepriekš minētais uztveršanas klauzulas izmantošanas piemērs ir tveršana pēc vērtības (sīkāku informāciju skatiet tālāk). Tverot ar atsauci, mainīgā atrašanās vieta (krātuve), piemēram,.g., ID, kas atrodas apkārt, ir pieejams lambda funkcijas korpusā. Tātad, mainot mainīgā vērtību lambda funkcijas ķermenī, mainīsies tā paša mainīgā vērtība apkārtējā darbības jomā. Lai to panāktu, pirms katra mainīgā, kas atkārtots uztveršanas klauzulā, ir zīme (&). To ilustrē šāda programma:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A';
auto fn = [& id, & ft, & ch] ()

id = 6; pēdas = 3.4; ch = 'B';
;
fn ();
cout << id << ", " <<  ft << ", " <<  ch << '\n';
atgriešanās 0;

Rezultāts ir:

    6, 3.4, B

Apstiprinot, ka mainīgo nosaukumi lambda izteiksmes funkcijas ķermenī ir vieni un tie paši mainīgie ārpus lambda izteiksmes.

Tveršana pēc vērtības

Uzņemot pēc vērtības, lambda funkcijas ķermenī tiek darīta pieejama mainīgā atrašanās vietas kopija un apkārtējā darbības joma. Lai gan lambda funkcijas ķermeņa mainīgais ir kopija, tā vērtību ķermeņa iekšienē tagad nevar mainīt. Lai panāktu tveršanu pēc vērtības, pirms katra mainīgā, kas atkārtots tveršanas klauzulā, nekas nav priekšā. To ilustrē šāda programma:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A';
auto fn = [id, pēdas, ch] ()

// id = 6; pēdas = 3.4; ch = 'B';
cout << id << ", " <<  ft << ", " <<  ch << '\n';
;
fn ();
id = 6; pēdas = 3.4; ch = 'B';
cout << id << ", " <<  ft << ", " <<  ch << '\n';
atgriešanās 0;

Rezultāts ir:

5, 2.3, A
6, 3.4, B

Ja komentāru indikators tiek noņemts, programma neapkopo. Sastādītājs izdos kļūdas ziņojumu, ka mainīgos, kas atrodas lambda izteiksmes funkcijas ķermeņa definīcijā, nevar mainīt. Lai gan mainīgos lielumus nevar mainīt lambda funkcijas iekšienē, tos var mainīt ārpus lambda funkcijas, kā parāda iepriekš minētās programmas izeja.

Jauktu uzņemšana

Uzņemšanu ar atsauci un tveršanu pēc vērtības var sajaukt, kā parāda šī programma:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A'; bool bl = patiess;
auto fn = [id, pēdas, & ch, & bl] ()

ch = 'B'; bl = nepatiesa;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
atgriešanās 0;

Rezultāts ir:

    5, 2.3, B, 0

Kad visi noķerti, ir norādīti:

Ja visi tveramie mainīgie tiek notverti ar atsauci, tad uztveršanas klauzulā pietiek tikai ar vienu un. To ilustrē šāda programma:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A'; bool bl = patiess;
auto fn = [&] ()

id = 6; pēdas = 3.4; ch = 'B'; bl = nepatiesa;
;
fn ();
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
atgriešanās 0;

Rezultāts ir:

6, 3.4, B, 0

Ja daži mainīgie jāuztver ar atsauci, bet citi - pēc vērtības, tad viens & būs visu atsauču pārstāvis, un pārējiem pirms katra nekas netiks norādīts, kā parāda šī programma:

izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A'; bool bl = patiess;
auto fn = [&, id, pēdas] ()

ch = 'B'; bl = nepatiesa;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
atgriešanās 0;

Rezultāts ir:

5, 2.3, B, 0

Ņemiet vērā, ka & atsevišķi (i.e., & kam neseko identifikators) jābūt pirmajai rakstzīmei uztveršanas klauzulā.

Kad visi ir notverti, pēc vērtības:

Ja visi tveramie mainīgie jāaptver pēc vērtības, tad uztveršanas klauzulā pietiek ar vienu =. To ilustrē šāda programma:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A'; bool bl = patiess;
auto fn = [=] ()

cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
atgriešanās 0;

Rezultāts ir:

5, 2.3, A, 1

Piezīme: = pašlaik ir tikai lasāms.

Ja daži mainīgie jāuztver vērtībai, bet citi - ar atsauci, tad viens = apzīmē visus tikai lasāmos kopētos mainīgos un pārējiem katram būs &, kā parāda šī programma:

# iekļaut
izmantojot nosaukumvietu std;
int main ()

int id = 5; pludiņš ft = 2.3; char ch = 'A'; bool bl = patiess;
auto fn = [=, & ch, & bl] ()

ch = 'B'; bl = nepatiesa;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
atgriešanās 0;

Rezultāts ir:

5, 2.3, B, 0

Ņemiet vērā, ka vienīgajam = jābūt pirmajai rakstzīmei uztveršanas klauzulā.

Klasiskās atzvanīšanas funkciju shēma ar Lambda izteiksmi

Šī programma parāda, kā klasisko atzvanīšanas funkciju shēmu var veikt ar izteiksmi lambda:

# iekļaut
izmantojot nosaukumvietu std;
char * izeja;
auto cba = [] (char out [])

izeja = ārā;
;
void basicFunc (char ievade [], void (* pt) (char []))

(* pt) (ievade);
cout<<"for principal function"<<'\n';

anulēt fn ()

cout<<"Now"<<'\n';

int main ()

char input [] = "atzvanīšanas funkcijai";
galvenaisFunc (ievade, cba);
fn ();
cout<atgriešanās 0;

Rezultāts ir:

par galveno funkciju
Tagad
atzvana funkcijai

Atgādinām, ka tad, kad lambda izteiksmes definīcija tiek piešķirta mainīgajam globālajā darbības sfērā, tā funkcijas ķermenis var redzēt globālos mainīgos, neizmantojot uztveršanas klauzulu.

Aizmugures-atgriešanās tips

Lambda izteiksmes atgriešanās veids ir automātisks, tas nozīmē, ka kompilators nosaka atgriešanās tipu no atgriešanās izteiksmes (ja tāda ir). Ja programmētājs patiešām vēlas norādīt atgriešanās veidu, viņš to darīs tāpat kā šajā programmā:

# iekļaut
izmantojot nosaukumvietu std;
auto fn = [] (int param) -> int

int atbilde = param + 3;
atbilde uz atbildi;
;
int main ()

auto mainīgais = fn (2);
cout << variab << '\n';
atgriešanās 0;

Rezultāts ir 5. Pēc parametru saraksta tiek ievadīts bultiņas operators. Tam seko atgriešanās veids (šajā gadījumā int).

Slēgšana

Apsveriet šādu koda segmentu:

struct Cla

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

Šeit Cla ir struktūras klases nosaukums.  Obj1 un obj2 ir divi objekti, kas tiks instantiated no struktūras klases. Lambda izteiksme ir līdzīga ieviešanā. Lambda funkcijas definīcija ir sava veida klase. Kad lambda funkcija tiek izsaukta (izsaukta), objekts tiek instantizēts no tās definīcijas. Šo objektu sauc par slēgšanu. Tas ir slēgšana, kas veic lambda paredzamo darbu.

Tomēr, kodējot izteiksmi lambda tāpat kā iepriekš minēto struktūru, obj1 un obj2 tiks aizstāti ar atbilstošo parametru argumentiem. To ilustrē šāda programma:

# iekļaut
izmantojot nosaukumvietu std;
auto fn = [] (int param1, int param2)

int atbilde = param1 + param2;
atbilde uz atbildi;
(2, 3);
int main ()

auto var = fn;
cout << var << '\n';
atgriešanās 0;

Rezultāts ir 5. Argumenti ir 2 un 3 iekavās. Ņemiet vērā, ka lambda izteiksmes funkcijas izsaukumam fn nav argumentu, jo argumenti jau ir kodēti funkcijas lambda definīcijas beigās.

Secinājums

Lambda izteiksme ir anonīma funkcija. Tas ir divās daļās: klase un objekts. Tās definīcija ir sava veida klase. Izsaucot izteicienu, no definīcijas tiek izveidots objekts. Šo objektu sauc par slēgšanu. Tas ir slēgšana, kas veic lambda paredzamo darbu.

Lai lambda izteiksme saņemtu mainīgo no ārējās funkcijas darbības jomas, tās funkcijas ķermenim ir nepieciešama ne tukša uztveršanas klauzula.

Populārākās Oculus App Lab spēles
Ja esat Oculus austiņu īpašnieks, jums ir jāsazinās par sānu ielādi. Sānu ielāde ir process, kurā austiņās tiek instalēts saturs, kas nav veikals. Sid...
10 labākās spēles, kuras spēlēt Ubuntu
Windows platforma ir bijusi viena no dominējošajām spēļu platformām, jo ​​mūsdienās tiek attīstīts milzīgs spēļu skaits, lai atbalstītu Windows. Vai k...
5 labākās arkādes spēles Linux
Mūsdienās datori ir nopietnas mašīnas, kuras izmanto spēlēšanai. Ja jūs nevarat iegūt jauno augsto rezultātu, jūs zināt, ko es domāju. Šajā ierakstā j...