C ++

Lambda išraiškos C ++

Lambda išraiškos C ++

Kodėl „Lambda Expression“?

Apsvarstykite šį teiginį:

    int myInt = 52;

Čia „myInt“ yra identifikatorius, vertė. 52 yra pažodinis, prvalue. Šiandien galima specialiai užkoduoti funkciją ir pastatyti ją į 52 poziciją. Tokia funkcija vadinama lambda išraiška. Apsvarstykite ir šią trumpą programą:

# įtraukti
naudojant vardų sritį std;
int fn (int par)

int atsakymas = par + 3;
grąžinti atsakymą;

int main ()

fn (5);
grąžinti 0;

Šiandien galima specialiai užkoduoti funkciją ir įdėti ją į funkcijos argumento 5, funkcijos iškvietimo, fn (5) poziciją. Tokia funkcija vadinama lambda išraiška. Toje padėtyje esanti lambda išraiška (funkcija) yra prvalue.

Bet koks pažodinis, išskyrus eilutės literalį, yra prvalue. Lambda išraiška yra specialus funkcijos dizainas, kuris atitiktų kodo pažodinį žodį. Tai anoniminė (neįvardinta) funkcija. Šiame straipsnyje paaiškinama nauja pagrindinė C ++ išraiška, vadinama lambda išraiška. Pagrindinės žinios C ++ kalba yra reikalavimas norint suprasti šį straipsnį.

Straipsnio turinys

  • „Lambda Expression“ iliustracija
  • Lambda išraiškos dalys
  • Fiksuoja
  • Klasikinė atgalinio skambinimo funkcijų schema su „Lambda Expression“
  • Galinis-grįžtamasis tipas
  • Uždarymas
  • Išvada

„Lambda Expression“ iliustracija

Šioje programoje funkcija, kuri yra lambda išraiška, priskiriama kintamajam:

# įtraukti
naudojant vardų sritį std;
auto fn = [] (int param)

int atsakymas = param + 3;
grąžinti atsakymą;
;
int main ()

auto kintamasis = fn (2);
cout << variab << '\n';
grąžinti 0;

Rezultatas yra:

    5

Už pagrindinės () funkcijos yra kintamasis fn. Jo tipas yra automatinis. „Auto“ šioje situacijoje reiškia, kad tikrąjį tipą, pvz., „Int“ arba „float“, nustato tinkamas priskyrimo operatoriaus operandas (=). Priskyrimo operatoriaus dešinėje yra lambda išraiška. Lambda išraiška yra funkcija be ankstesnio grąžinimo tipo. Atkreipkite dėmesį į laužtinių skliaustų naudojimą ir padėtį, []. Funkcija grąžina 5, int, kuris nustatys fn tipą.

Pagrindinėje () funkcijoje yra teiginys:

    auto kintamasis = fn (2);

Tai reiškia, kad fn už main (), yra funkcijos identifikatorius. Jo numanomi parametrai yra tokie, kaip lambda išraiškos. Kintamojo tipas yra automatinis.

Atkreipkite dėmesį, kad lambda išraiška baigiasi kabliataškiu, kaip ir klasės ar struktūros apibrėžimas, baigiasi kabliataškiu.

Šioje programoje funkcija, kuri yra lambda išraiška, grąžinanti 5 reikšmę, yra argumentas kitai funkcijai:

# įtraukti
naudojant vardų sritį std;
anuliuoti otherfn (int no1, int (* ptr) (int))

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

int main ()

otherfn (4, [] (int param)

int atsakymas = param + 3;
grąžinti atsakymą;
);
grąžinti 0;

Rezultatas yra:

    4 5

Čia yra dvi funkcijos, lambda išraiška ir kitafn () funkcija. Lambda išraiška yra antrasis „otherfn“ () argumentas, vadinamas pagrindine (). Atkreipkite dėmesį, kad „lambda“ funkcija (išraiška) šiame kvietime nesibaigia kabliataškiu, nes čia tai yra argumentas (ne atskira funkcija).

Funkcijos „lambda“ parametras, apibrėžiantis funkciją „otherfn ()“, yra funkcijos rodyklė. Žymeklis turi pavadinimą, ptr. Pavadinimas ptr yra naudojamas „otherfn ()“ apibrėžime, norint iškviesti „lambda“ funkciją.

Pareiškimas,

    int no2 = (* ptr) (2);

Pagal „otherfn ()“ apibrėžimą, jis iškviečia „lambda“ funkciją argumentu 2. Skambučio grąžinimo vertė „(* ptr) (2)“ iš „lambda“ funkcijos priskiriama „no2“.

Pirmiau nurodyta programa taip pat parodo, kaip „lambda“ funkciją galima naudoti C ++ atgalinio skambinimo funkcijos schemoje.

Lambda išraiškos dalys

Tipiškos lambda funkcijos dalys yra šios:

    [] ()
  • [] yra fiksavimo sąlyga. Jis gali turėti daiktų.
  • () skirtas parametrų sąrašui.
  • skirtas funkcijos kūnui. Jei funkcija yra atskirai, ji turėtų baigtis kabliataškiu.

Fiksuoja

„Lambda“ funkcijos apibrėžimą galima priskirti kintamajam arba naudoti kaip argumentą kitam funkcijos iškvietimui. Tokio funkcijos iškvietimo apibrėžimas turėtų būti parametras, funkcijos rodyklė, atitinkanti lambda funkcijos apibrėžimą.

Lambda funkcijos apibrėžimas skiriasi nuo įprasto funkcijos apibrėžimo. Jis gali būti priskirtas kintamajam visuotinėje srityje; ši funkcija, priskirta kintamajam, taip pat gali būti užkoduota kitos funkcijos viduje. Priskirtas visuotinės apimties kintamajam, jo ​​kūnas gali matyti kitus visuotinės apimties kintamuosius. Priskirtas kintamajam įprastos funkcijos apibrėžimo viduje, jo kūnas gali matyti kitus kintamuosius funkcijų srityje tik su fiksavimo sąlygos pagalba, [].

Užfiksavimo sąlyga [], dar žinoma kaip „lambda“ įvedėjas, leidžia kintamuosius iš aplinkinės (funkcijos) srities siųsti į „lambda“ išraiškos funkcijos kūną. Sakoma, kad lambda išraiškos funkcijos kūnas kintamąjį fiksuoja, kai gauna objektą. Be fiksavimo sąlygos [], kintamojo negalima siųsti iš supančios srities į lambda išraiškos funkcijos kūną. Ši programa iliustruoja tai su pagrindine () funkcijos apimtimi kaip su aplinka:

# įtraukti
naudojant vardų sritį std;
int main ()

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

cout << id << '\n';
;
fn ();
grąžinti 0;

Rezultatas yra 5. Be pavadinimo, id, viduje [], lambda išraiška nebūtų matžiusi main (main) funkcijos srities.

Užfiksavimas naudojant nuorodą

Pirmiau pateiktas fiksavimo sąlygos naudojimo pavyzdys yra fiksavimas pagal vertę (žr. Išsamią informaciją toliau). Gaudant pagal nuorodą, kintamojo vieta (saugykla), t.g., aukščiau esantis ID, esantis aplinkoje, yra prieinamas lambda funkcijos kūne. Taigi, pakeitus kintamojo vertę „lambda“ funkcijos kūne, bus pakeista to paties kintamojo vertė supančioje srityje. Prieš kiekvieną kintamąjį, pakartotą fiksavimo sąlygoje, prieš tai pažymimas ženklas (&), kad tai būtų pasiekta. Tai iliustruoja ši programa:

# įtraukti
naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A';
auto fn = [& id, & ft, & ch] ()

id = 6; pėdos = 3.4; ch = 'B';
;
fn ();
cout << id << ", " <<  ft << ", " <<  ch << '\n';
grąžinti 0;

Rezultatas yra:

    6, 3.4, B

Patvirtinant, kad kintamųjų pavadinimai lambda išraiškos funkcijos kūne yra skirti tiems patiems kintamiesiems, kurie nėra lambda išraiškos ribose.

Užfiksuoti pagal vertę

Užfiksuojant pagal vertę, lambda funkcijos kūne pateikiama kintamojo buvimo vietos ir jo apimties kopija. Nors lambda funkcijos kūno kintamasis yra kopija, jo vertės kūno viduje pakeisti dabar negalima. Norint pasiekti fiksavimą pagal vertę, prieš kiekvieną fiksavimo sakinyje pakartotą kintamąjį nieko nėra. Tai iliustruoja ši programa:

# įtraukti
naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A';
auto fn = [id, ft, ch] ()

// id = 6; pėdos = 3.4; ch = 'B';
cout << id << ", " <<  ft << ", " <<  ch << '\n';
;
fn ();
id = 6; pėdos = 3.4; ch = 'B';
cout << id << ", " <<  ft << ", " <<  ch << '\n';
grąžinti 0;

Rezultatas yra:

5, 2.3, A
6, 3.4, B

Pašalinus komentaro indikatorių, programa nekompiliuos. Kompiliatorius išleis klaidos pranešimą, kad kintamieji, esantys funkcijos kūno apibrėžtyje lambda išraiškoje, negali būti pakeisti. Nors kintamieji negali būti pakeisti „lambda“ funkcijos viduje, jie gali būti pakeisti už „lambda“ funkcijos ribų, kaip rodo pirmiau pateiktos programos išvestis.

Maišymas užfiksuoti

Gaudymas pagal nuorodą ir fiksavimas pagal vertę gali būti mišrus, kaip rodo ši programa:

# įtraukti
naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A'; bool bl = teisinga;
auto fn = [id, ft, & ch, & bl] ()

ch = 'B'; bl = klaidinga;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
grąžinti 0;

Rezultatas yra:

    5, 2.3, B, 0

Kai visi užfiksuoti, yra nuoroda:

Jei visi fiksuotini kintamieji užfiksuojami remiantis nuoroda, tada fiksavimo sąlygoje pakaks tik vieno ir pakaks. Tai iliustruoja ši programa:

# įtraukti
naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A'; bool bl = tiesa;
auto fn = [&] ()

id = 6; pėdos = 3.4; ch = 'B'; bl = klaidinga;
;
fn ();
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
grąžinti 0;

Rezultatas yra:

6, 3.4, B, 0

Jei kai kuriuos kintamuosius reikia užfiksuoti pagal nuorodas, o kitus - pagal vertę, tada vienas & bus visas nuorodas, o po likusių nebus nieko prieš, kaip rodo ši programa:

naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A'; bool bl = tiesa;
auto fn = [&, id, ft] ()

ch = 'B'; bl = klaidinga;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
grąžinti 0;

Rezultatas yra:

5, 2.3, B, 0

Atkreipkite dėmesį, kad & vienas (t.e., & po kurio nenurodytas identifikatorius) turi būti pirmasis užfiksavimo sąlygos simbolis.

Kai visi užfiksuoti, yra pagal vertę:

Jei visi fiksuotini kintamieji turi būti užfiksuoti pagal vertę, tada fiksavimo sąlygoje pakaks tik vieno =. Tai iliustruoja ši programa:

# įtraukti
naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A'; bool bl = teisinga;
auto fn = [=] ()

cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
grąžinti 0;

Rezultatas yra:

5, 2.3, A, 1

Pastaba: = dabar yra tik skaitomas.

Jei kai kuriuos kintamuosius reikia užfiksuoti pagal vertę, o kitus - pagal nuorodą, tada vienas = reprezentuos visus tik skaityti nukopijuotus kintamuosius, o likusieji turės &, kaip rodo ši programa:

# įtraukti
naudojant vardų sritį std;
int main ()

int id = 5; plūdės pėda = 2.3; char ch = 'A'; bool bl = tiesa;
auto fn = [=, & ch, & bl] ()

ch = 'B'; bl = klaidinga;
cout << id << ", " << ft << ", " << ch << ", " << bl << '\n';
;
fn ();
grąžinti 0;

Rezultatas yra:

5, 2.3, B, 0

Atkreipkite dėmesį, kad tik = turi būti pirmasis simbolis fiksavimo sąlygoje.

Klasikinė atgalinio skambinimo funkcijų schema su „Lambda Expression“

Ši programa parodo, kaip galima atlikti klasikinę atgalinio skambinimo funkcijos schemą naudojant lambda išraišką:

# įtraukti
naudojant vardų sritį std;
char * išėjimas;
auto cba = [] (char out [])

išėjimas = išėjimas;
;
void pagrindinėFunc (char įvestis [], void (* pt) (char []))

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

anuliuoti fn ()

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

int main ()

char input [] = "skambinimo funkcijai";
pagrindinisFunc (įvestis, cba);
fn ();
cout<grąžinti 0;

Rezultatas yra:

pagrindinei funkcijai
Dabar
skambinimo funkcijai

Primename, kad kai kintamajam globalioje srityje priskiriamas lambda išraiškos apibrėžimas, jo funkcijos kūnas gali matyti visuotinius kintamuosius nenaudodamas fiksavimo sąlygos.

Galinis-grįžtamasis tipas

Lambda išraiškos grąžinimo tipas yra automatinis, o tai reiškia, kad kompiliatorius nustato grąžinimo tipą iš grąžinimo išraiškos (jei yra). Jei programuotojas tikrai nori nurodyti grąžinimo tipą, jis tai padarys taip, kaip šioje programoje:

# įtraukti
naudojant vardų sritį std;
auto fn = [] (int param) -> int

int atsakymas = param + 3;
grąžinti atsakymą;
;
int main ()

auto kintamasis = fn (2);
cout << variab << '\n';
grąžinti 0;

Išvestis yra 5. Po parametrų sąrašo įvedamas rodyklių operatorius. Po to nurodomas grąžinimo tipas (šiuo atveju int).

Uždarymas

Apsvarstykite šį kodo segmentą:

struct Cla

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

Čia Cla yra struktūros klasės pavadinimas.  „Obj1“ ir „obj2“ yra du objektai, kurie bus nedelsiant išstruktūrinės klasės. Lambda išraiška yra panaši įgyvendinant. Lambda funkcijos apibrėžimas yra tam tikra klasė. Kai lambda funkcija yra iškviečiama (iškviečiama), objektas išaiškinamas pagal jo apibrėžimą. Šis objektas vadinamas uždarymu. Būtent uždarymas atlieka tą darbą, kurio tikimasi atlikti „lambda“.

Tačiau koduojant „lambda“ išraišką, kaip ir anksčiau pateiktą struktūrą, obj1 ir obj2 bus pakeisti atitinkamų parametrų argumentais. Tai iliustruoja ši programa:

# įtraukti
naudojant vardų sritį std;
auto fn = [] (int param1, int param2)

int atsakymas = param1 + param2;
grąžinti atsakymą;
(2, 3);
int main ()

auto var = fn;
cout << var << '\n';
grąžinti 0;

Išvestis yra 5. Argumentai yra 2 ir 3 skliaustuose. Atkreipkite dėmesį, kad „lambda“ išraiškos funkcijos iškvietimas fn neturi argumento, nes argumentai jau buvo užkoduoti „lambda“ funkcijos apibrėžimo pabaigoje.

Išvada

Lambda išraiška yra anoniminė funkcija. Tai dvi dalys: klasė ir objektas. Jo apibrėžimas yra tam tikra klasė. Kai išsireiškimas vadinamas, iš apibrėžimo suformuojamas objektas. Šis objektas vadinamas uždarymu. Būtent uždarymas atlieka tą darbą, kurio tikimasi atlikti „lambda“.

Norint, kad „lambda“ išraiška gautų kintamąjį iš išorinės funkcijos srities, į jos funkcijos kūną reikia ne tuščio fiksavimo sakinio.

Kaip pakeisti pelės ir jutiklinių plokščių slinkimo kryptį sistemoje „Windows 10“
Pelė ir Jutiklinė dalisTai ne tik palengvina skaičiavimus, bet ir efektyvesnį bei mažiau laiko reikalaujantį. Mes neįsivaizduojame gyvenimo be šių pri...
Kaip pakeisti pelės žymeklio ir žymeklio dydį, spalvą ir schemą sistemoje „Windows 10“
„Windows 10“ pelės žymeklis ir žymeklis yra labai svarbūs operacinės sistemos aspektai. Tai galima pasakyti ir apie kitas operacines sistemas, taigi, ...
Nemokami ir atvirojo kodo žaidimų varikliai, skirti kurti „Linux“ žaidimus
Šiame straipsnyje bus pateiktas nemokamų ir atvirojo kodo žaidimų variklių, kurie gali būti naudojami kuriant 2D ir 3D žaidimus „Linux“, sąrašas. Toki...