Lambda išraiškos C ++

Lambda Expressions C



Kodėl „Lambda Expression“?

Apsvarstykite šį teiginį:

tarptmyInt= 52;

Čia „myInt“ yra identifikatorius, vertybė. 52 yra pažodinis, prvalue. Šiandien galima specialiai koduoti funkciją ir nustatyti ją į 52. Tokia funkcija vadinama lambda išraiška. Taip pat apsvarstykite šią trumpą programą:







#įtraukti

naudojant vardų sritisvalandų;

tarptfn(tarptper)

{

tarptatsakyk=per+ 3;

grįžtiatsakyk;

}


tarptpagrindinis()

{

fn(5);



grįžti 0;

}

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



Bet kuris literalas, išskyrus eilutę, yra prvalue. „Lambda“ išraiška yra specialus funkcijų dizainas, kuris atitiktų pažodinį kodą. Tai anoniminė (neįvardinta) funkcija. Šiame straipsnyje paaiškinama nauja pirminė C ++ išraiška, vadinama lambda išraiška. Norint suprasti šį straipsnį, būtinos pagrindinės C ++ žinios.



Straipsnio turinys

Lambda išraiškos iliustracija

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





#įtraukti

naudojant vardų sritisvalandų;

automatinisfn= [](tarptsustabdyti)

{

tarptatsakyk=sustabdyti+ 3;

grįžtiatsakyk;

};


tarptpagrindinis()

{

automatiniskintamasis=fn(2);

kaina <<kintamasis<< ' n';


grįžti 0;

}

Išėjimas yra:

5

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



Pagrindinėje () funkcijoje yra teiginys:

automatiniskintamasis=fn(2);

Tai reiškia, kad fn išorėje main () yra funkcijos identifikatorius. Jo numanomi parametrai yra lambda išraiškos parametrai. Kintamojo tipas yra automatinis.

Atminkite, 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 kitos funkcijos argumentas:

#įtraukti

naudojant vardų sritisvalandų;

tuštumakitasfn(tarpt1,tarpt (*ptr)(tarpt))

{

tarpt2= (*ptr)(2);

kaina <<Nr1<< '' <<2<< ' n';

}


tarptpagrindinis()

{

kitasfn(4,[](tarptsustabdyti)

{

tarptatsakyk=sustabdyti+ 3;

grįžtiatsakyk;

});


grįžti 0;
}

Išėjimas yra:

Keturi, penki

Čia yra dvi funkcijos - lambda išraiška ir funkcija otherfn (). Lambda išraiška yra antrasis argumentas otherfn (), vadinamas pagrindiniu (). Atminkite, kad lambda funkcija (išraiška) šiame skambutyje nesibaigia kabliataškiu, nes čia tai yra argumentas (o ne atskira funkcija).

Funkcijos otherfn () apibrėžime lambda funkcijos parametras yra funkcijos rodyklė. Rodyklė turi pavadinimą, ptr. Pavadinimas „ptr“ naudojamas „otherfn“ () apibrėžtyje, kad iškviestų lambda funkciją.

Pareiškimas,

tarpt2= (*ptr)(2);

Apibrėžime otherfn () jis iškviečia lambda funkciją su argumentu 2. Skambučio grąžinimo vertė „(*ptr) (2)“ iš funkcijos lambda priskiriama nr2.

Aukščiau pateikta programa taip pat parodo, kaip lambda funkciją galima naudoti C ++ atšaukimo funkcijos schemoje.

„Lambda Expression“ dalys

Tipiškos lambda funkcijos dalys yra šios:

[] () {}
  • [] yra fiksavimo sąlyga. Jame gali būti daiktų.
  • () skirtas parametrų sąrašui.
  • {} skirtas funkcijai. Jei funkcija veikia atskirai, ji turėtų baigtis kabliataškiu.

Užfiksuoja

Funkcijos lambda apibrėžimas gali būti priskirtas kintamajam arba naudojamas kaip argumentas kitam funkcijos iškvietimui. Tokios funkcijos iškvietimo apibrėžimas turėtų turėti parametrą, žymeklį į funkciją, atitinkančią lambda funkcijos apibrėžimą.

Lambda funkcijos apibrėžimas skiriasi nuo įprastos funkcijos apibrėžimo. Jis gali būti priskirtas kintamajam visuotinėje apimtyje; šią funkciją, priskirtą kintamajam, taip pat galima koduoti kitos funkcijos viduje. Priskyrus pasaulinės apimties kintamąjį, jo korpusas gali matyti kitus pasaulinės apimties kintamuosius. Priskirtas kintamajam įprastoje funkcijos apibrėžtyje, jo korpusas gali matyti kitus funkcijos apimties kintamuosius tik padedant fiksavimo sąlygai [].

Užfiksavimo sąlyga [], dar vadinama lambda įvedimo priemone, leidžia kintamuosius siųsti iš aplinkinės (funkcijos) apimties į lambda išraiškos funkcijos turinį. Sakoma, kad lambda išraiškos funkcijos kūnas fiksuoja kintamąjį, kai jis gauna objektą. Be fiksavimo sąlygos [], kintamasis negali būti siunčiamas iš aplinkinės apimties į lambda išraiškos funkcijų turinį. Ši programa tai iliustruoja, o pagrindinė () funkcijos apimtis yra kaip aplinkinė sritis:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5;


automatinisfn= [id]()

{

kaina <<id<< ' n';

};

fn();


grįžti 0;

}

Išėjimas yra 5 . Be pavadinimo, id, [] viduje, lambda išraiška nebūtų matęs pagrindinės () funkcijos apimties kintamojo id.

Fiksavimas pagal nuorodą

Aukščiau pateiktas fiksavimo sąlygos naudojimo pavyzdys yra fiksavimas pagal vertę (žr. Išsamią informaciją žemiau). Fiksuojant pagal nuorodą, kintamojo vieta (saugykla), pvz., ID aukščiau, aplinkinėje srityje, yra prieinama lambda funkcijos korpuso viduje. Taigi, pakeitus kintamojo reikšmę lambda funkcijos korpuse, pasikeis to paties kintamojo reikšmė aplinkinėje srityje. Prieš kiekvieną fiksavimo sąlygoje pakartotą kintamąjį prieš tai yra simbolis (&). Toliau pateikta programa tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“;

automatinisfn= [&id,&pėdų,&ch]()

{

id= 6;pėdų= 3.4;ch= „B“;

};

fn();

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ' n';

grįžti 0;

}

Išėjimas yra:

6, 3.4, B.

Patvirtinimas, kad kintamųjų pavadinimai „lambda“ išraiškos funkcijų turinyje yra skirti tiems patiems kintamiesiems už lambda išraiškos ribų.

Fiksavimas pagal vertę

Fiksuojant pagal vertę, lambda funkcijos korpuso viduje pateikiama kintamojo vietos ir aplinkinės apimties kopija. Nors kintamasis lambda funkcijos korpuso viduje yra kopija, jo vertės kol kas negalima keisti kūno viduje. Norint pasiekti užfiksavimą pagal vertę, prieš kiekvieną kintamąjį, pakartotą fiksavimo sąlygoje, nėra nieko. Toliau pateikta programa tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“;

automatinisfn= [id, pėdos, sk]()

{

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

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ' n';

};

fn();

id= 6;pėdų= 3.4;ch= „B“;

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ' n';

grįžti 0;

}

Išėjimas yra:

5, 2.3, A.

6, 3.4, B.

Jei pašalinamas komentaro indikatorius, programa nekompiliuos. Kompiliatorius pateiks klaidos pranešimą, kad kintamieji, esantys funkcijos turinio lambda išraiškos apibrėžime, negali būti pakeisti. Nors kintamųjų negalima pakeisti „lambda“ funkcijos viduje, juos galima pakeisti už lambda funkcijos ribų, kaip rodo aukščiau pateiktos programos išvestis.

Fiksavimo maišymas

Fiksavimas pagal nuorodą ir fiksavimas pagal vertę gali būti sumaišytas, kaip parodyta šioje programoje:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“; boolbl= tiesa;


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

{

ch= „B“;bl= klaidinga;

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


grįžti 0;

}

Išėjimas yra:

5, 2.3, B, 0

Kai viskas užfiksuota, vadovaukitės:

Jei visi kintamieji, kuriuos reikia užfiksuoti, yra užfiksuoti pagal nuorodą, tada užfiksavimo sąlygoje pakaks tik vieno &. Toliau pateikta programa tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“; boolbl= tiesa;


automatinisfn= [&]()

{

id= 6;pėdų= 3.4;ch= „B“;bl= klaidinga;

};

fn();

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ',' <<bl<< ' n';


grįžti 0;

}

Išėjimas yra:

6, 3.4, B, 0

Jei kai kurie kintamieji turi būti užfiksuoti pagal nuorodą, o kiti - pagal vertę, tada vienas ir parodys visas nuorodas, o prieš kitus nebus nieko, kaip parodyta šioje programoje:

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“; boolbl= tiesa;


automatinisfn= [&, id, ft]()

{

ch= „B“;bl= klaidinga;

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


grįžti 0;

}

Išėjimas yra:

5, 2.3, B, 0

Atminkite, kad „&“ (t. Y. Ir po to nenurodomas identifikatorius) turi būti pirmasis fiksavimo sąlygos simbolis.

Kai visi užfiksuoti, yra pagal vertę:

Jei visi užfiksuojami kintamieji turi būti užfiksuoti pagal vertę, tada užfiksavimo sąlygoje užtenka tik vieno =. Toliau pateikta programa tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()
{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“; boolbl= tiesa;


automatinisfn= [=]()

{

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


grįžti 0;


}

Išėjimas yra:

5, 2.3, A, 1

Pastaba : = šiuo metu yra tik skaitomas.

Jei kai kurie kintamieji turi būti užfiksuoti pagal vertę, o kiti-pagal nuorodą, tada vienas = parodys visus tik skaitymo kopijuojamus kintamuosius, o likusieji turės &, kaip parodyta šioje programoje:

#įtraukti

naudojant vardų sritisvalandų;

tarptpagrindinis()

{

tarptid= 5; plūdėpėdų= 2.3; anglisch= „Į“; boolbl= tiesa;


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

{

ch= „B“;bl= klaidinga;

kaina <<id<< ',' <<pėdų<< ',' <<ch<< ',' <<bl<< ' n';

};

fn();


grįžti 0;

}

Išėjimas yra:

5, 2.3, B, 0

Atminkite, kad = vien tik turi būti pirmasis užfiksavimo sąlygos simbolis.

Klasikinė atgalinio ryšio funkcijų schema su „Lambda Expression“

Ši programa parodo, kaip galima atlikti klasikinę atšaukimo funkcijų schemą naudojant lambda išraišką:

#įtraukti

naudojant vardų sritisvalandų;

anglis *produkcija;


automatiniscba= [](anglisišeiti[])

{

produkcija=išeiti;

};



tuštumamainFunc(anglisįvesties[],tuštuma (*dėl)(anglis[]))

{

(*dėl)(įvesties);

kaina<<„pagrindinei funkcijai“<<' n';

}


tuštumafn()

{

kaina<<'Dabar'<<' n';

}


tarptpagrindinis()

{

anglisįvesties[] = „atgalinio ryšio funkcijai“;

mainFunc(įvestis, cba);

fn();

kaina<<produkcija<<' n';



grįžti 0;

}

Išėjimas yra:

pagrindinei funkcijai

Dabar

atgalinio ryšio funkcijai

Prisiminkite, kad kai lambda išraiškos apibrėžimas priskiriamas kintamajam visuotinėje apimtyje, jo funkcijų struktūra gali matyti visuotinius kintamuosius nenaudodama fiksavimo sąlygos.

Galinis grąžinimo 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ų sritisvalandų;

automatinisfn= [](tarptsustabdyti) -> tarpt

{

tarptatsakyk=sustabdyti+ 3;

grįžtiatsakyk;

};


tarptpagrindinis()

{

automatiniskintamasis=fn(2);

kaina <<kintamasis<< ' n';


grįžti 0;

}

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

Uždarymas

Apsvarstykite šį kodo segmentą:

strukturaCla

{

tarptid= 5;

anglisch= 'iki';

}obj1, obj2;

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

Tačiau koduojant lambda išraišką, kaip nurodyta aukščiau esančioje struktūroje, obj1 ir obj2 bus pakeisti atitinkamų parametrų argumentais. Toliau pateikta programa tai iliustruoja:

#įtraukti

naudojant vardų sritisvalandų;

automatinisfn= [](tarptparam1,tarptparam2)

{

tarptatsakyk=param1+param2;

grįžtiatsakyk;

} (2,3);


tarptpagrindinis()

{

automatiniskur=fn;

kaina <<kur<< ' n';


grįžti 0;

}

Rezultatas yra 5. Argumentai 2 ir 3 skliausteliuose. Atminkite, kad lambda išraiškos funkcijos iškvietimas, fn, nepriima jokių argumentų, nes argumentai jau yra užkoduoti lambda funkcijos apibrėžimo pabaigoje.

Išvada

Lambda išraiška yra anoniminė funkcija. Jis susideda iš dviejų dalių: klasės ir objekto. Jo apibrėžimas yra tam tikra klasė. Kai išraiška vadinama, iš apibrėžimo susidaro objektas. Šis objektas vadinamas uždarymu. Uždarymas atlieka darbą, kurio tikimasi atlikti lambda.

Kad lambda išraiška gautų kintamąjį iš išorinės funkcijų apimties, jos funkcijų turinyje turi būti ne tuščia fiksavimo sąlyga.