Miért a Lambda Expression?
Tekintsük a következő állítást:
intmyInt= 52;Itt a myInt egy azonosító, egy érték. Az 52 szó szerinti, prvalue. Ma már lehetőség van egy függvény speciális kódolására és 52. pozícióba állítására. Az ilyen függvényt lambda kifejezésnek nevezzük. Vegye figyelembe a következő rövid programot is:
#befoglalni
segítségével névtérórák;
intfn(intkeresztül)
{
intválasz=keresztül+ 3;
Visszatérésválasz;
}
intfő-()
{
fn(5);
Visszatérés 0;
}
Ma már lehetőség van egy függvény speciális kódolására és az 5, az függvényhívás, az fn (5) argumentum pozíciójába helyezésére. Az ilyen függvényt lambda kifejezésnek nevezik. A lambda kifejezés (függvény) ebben a helyzetben egy érték.
Bármely literál, kivéve a karakterláncot, prvalue. A lambda kifejezés egy speciális funkció, amely szó szerint 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 C ++ nyelv alapismerete elengedhetetlen a cikk megértéséhez.
Cikk tartalma
- Lambda kifejezés illusztrációja
- A Lambda Expression részei
- Rögzíti
- Klasszikus visszahívási funkció séma Lambda kifejezéssel
- A trailing-return típus
- Bezárás
- Következtetés
Lambda kifejezés illusztrációja
A következő programban egy függvény, amely egy lambda kifejezés, hozzá van rendelve egy változóhoz:
#befoglalni
segítségével névtérórák;
autofn= [](intálljon meg)
{
intválasz=álljon meg+ 3;
Visszatérésválasz;
};
intfő-()
{
autováltozó=fn(2);
költség <<változó<< ' n';
Visszatérés 0;
}
A kimenet:
5A main () függvényen kívül van az fn változó. Típusa automata. Az automatikus ebben a helyzetben azt jelenti, hogy a tényleges típust, például int vagy float, a hozzárendelő operátor jobb operandusa határozza meg (=). A hozzárendelési 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ójel használatát és helyzetét, []. A függvény 5, int értéket ad vissza, amely meghatározza az fn típusát.
A main () függvényben a következő állítás található:
autováltozó=fn(2);Ez azt jelenti, hogy az fn kívül a main () egy funkció azonosítója. Implicit paraméterei a lambda kifejezés paraméterei. A változó típusa automatikus.
Ne feledje, hogy a lambda kifejezés pontosvesszővel végződik, akárcsak az osztály vagy struktúra meghatározása, pontosvesszővel végződik.
A következő programban egy függvény, amely az 5 értékét visszaadó lambda kifejezés, egy argumentum egy másik függvényhez:
#befoglalnisegítségével névtérórák;
üresegyébfn(intno1,int (*ptr)(int))
{
intno2= (*ptr)(2);
költség <<no1<< '' <<no2<< ' n';
}
intfő-()
{
egyébfn(4,[](intálljon meg)
{
intválasz=álljon meg+ 3;
Visszatérésválasz;
});
Visszatérés 0;
}
A kimenet:
Négy ötItt két függvény létezik, a lambda kifejezés és a otherfn () függvény. A lambda kifejezés a mainfn () második argumentuma, amelyet a main () -ban hívnak. Vegye figyelembe, hogy a lambda függvény (kifejezés) ebben a hívásban nem végződik pontosvesszővel, mert itt ez egy argumentum (nem önálló függvény).
A lambda függvény paramétere a otherfn () függvény definíciójában egy függvény mutatója. A mutató neve, ptr. A ptr nevet a otherfn () definícióban a lambda függvény meghívására használják.
Az állítás,
intno2= (*ptr)(2);A otherfn () definícióban 2 -es argumentummal hívja meg a lambda függvényt. A hívás visszatérési értéke, a (*ptr) (2) 'a lambda függvényből, a no2 -hez van hozzárendelve.
A fenti program azt is bemutatja, hogy a lambda függvény hogyan használható a C ++ visszahívási funkció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. Lehet benne elem.
- () a paraméterlista.
- {} a függvénytesthez tartozik. Ha a függvény egyedül áll, akkor pontosvesszővel kell befejeződnie.
Rögzíti
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, mutatónak kell lennie 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énydefiníciótól. A globális hatókör változójához rendelhető; ez a változóhoz rendelt függvény egy másik függvényen belül is kódolható. Globális hatókör -változóhoz rendelve a törzs más változókat is láthat a globális hatókörben. Ha egy normál függvénydefiníción belüli változóhoz rendelik, annak törzse csak a rögzítési záradék segítségével láthatja a függvény hatókörének többi változóját, [].
A rögzítési záradék [], más néven lambda-bevezető, lehetővé teszi a változók küldését a környező (függvény) hatókörből a lambda kifejezés funkciótestébe. A lambda kifejezés függvénytörzse állítólag rögzíti a változót, amikor megkapja az objektumot. A rögzítési záradék [] nélkül nem lehet változót küldeni a környező hatókörből a lambda kifejezés funkciótestébe. A következő program ezt szemlélteti, a fő () függvénykörrel, mint a környező hatókörrel:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5;
autofn= [id]()
{
költség <<id<< ' n';
};
fn();
Visszatérés 0;
}
A kimenet az 5 . A név, id nélkül a [] belsejében a lambda kifejezés nem látta volna a main () függvény hatókörének változó azonosítóját.
Rögzítés hivatkozással
A rögzítési záradék fenti példa szerinti használata érték szerinti rögzítés (lásd az alábbi részleteket). A referenciaként történő rögzítés során a változó helyét (tárolását), például a fenti azonosítót, a környező hatókörben elérhetővé teszik a lambda függvénytestben. Tehát a lambda függvénytestben lévő 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éséhez. Az alábbi program ezt szemlélteti:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK';
autofn= [&azonosító,&ft,&ch]()
{
id= 6;ft= 3.4;ch= 'B';
};
fn();
költség <<id<< ',' <<ft<< ',' <<ch<< ' n';
Visszatérés 0;
}
A kimenet:
6, 3,4, B.Annak megerősítése, hogy a lambda kifejezés függvénytörzsében található változónevek ugyanazokra a változókra vonatkoznak a lambda kifejezésen kívül.
Érték szerinti rögzítés
Az érték szerinti rögzítés során a lambda függvénytestben elérhetővé válik a változó helyének másolata, a környező hatókör. Bár a lambda függvénytestben lévő változó másolat, értéke a testen belül jelenleg nem módosítható. 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. Az alábbi program ezt szemlélteti:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK';
autofn= [id, ft, ch]()
{
// id = 6; ft = 3,4; ch = 'B';
költség <<id<< ',' <<ft<< ',' <<ch<< ' n';
};
fn();
id= 6;ft= 3.4;ch= 'B';
költség <<id<< ',' <<ft<< ',' <<ch<< ' n';
Visszatérés 0;
}
A kimenet:
5, 2.3, A.6, 3,4, B.
Ha a megjegyzésjelző eltávolításra kerül, a program nem fordítja le. A fordító hibaüzenetet ad ki, miszerint a függvénytest lambda kifejezés definíciójában szereplő változók nem módosíthatók. Bár a változók nem módosíthatók a lambda függvényen belül, a lambda függvényen kívül is módosíthatók, ahogy a fenti program kimenete is mutatja.
Rögzítés keverése
A referencia alapján történő rögzítés és az érték szerinti rögzítés keverhető, ahogy az alábbi program mutatja:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;
autofn= [id, ft,&ch,&bl]()
{
ch= 'B';bl= hamis;
költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';
};
fn();
Visszatérés 0;
}
A kimenet:
5, 2,3, B, 0Ha minden rögzítésre került, hivatkozás:
Ha az összes rögzítendő változót hivatkozás rögzíti, akkor csak egy & elegendő lesz a rögzítési záradékban. Az alábbi program ezt szemlélteti:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;
autofn= [&]()
{
id= 6;ft= 3.4;ch= 'B';bl= hamis;
};
fn();
költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';
Visszatérés 0;
}
A kimenet:
6, 3,4, B, 0Ha egyes változókat referenciával, másokat értékkel kell rögzíteni, akkor az egyik & az összes hivatkozást reprezentálja, a többit pedig nem előzi meg semmi, ahogy az alábbi program mutatja:
segítségével névtérórák;intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;
autofn= [&, id, ft]()
{
ch= 'B';bl= hamis;
költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';
};
fn();
Visszatérés 0;
}
A kimenet:
5, 2,3, B, 0Ne feledje, hogy az & önmagában (azaz, és az azonosító után nem) kell lennie a rögzítési záradék első karakterének.
Ha minden rögzítve van, érték szerint:
Ha az összes rögzítendő változót érték szerint kell rögzíteni, akkor csak egy = elegendő a rögzítési záradékban. Az alábbi program ezt szemlélteti:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;
autofn= [=]()
{
költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';
};
fn();
Visszatérés 0;
}
A kimenet:
5, 2.3, A, 1jegyzet : = jelenleg csak olvasható.
Ha egyes változókat értékkel, másokat pedig hivatkozással kell rögzíteni, akkor az egyik = az összes írásvédett másolt változót reprezentálja, a többi pedig & -et, mint a következő program mutatja:
#befoglalnisegítségével névtérórák;
intfő-()
{
intid= 5; úszóft= 2.3; charch= 'NAK NEK'; boolbl= igaz;
autofn= [=,&ch,&bl]()
{
ch= 'B';bl= hamis;
költség <<id<< ',' <<ft<< ',' <<ch<< ',' <<bl<< ' n';
};
fn();
Visszatérés 0;
}
A kimenet:
5, 2,3, B, 0Ne feledje, hogy a = egyedül kell, hogy legyen a rögzítési záradék első karaktere.
Klasszikus visszahívási funkció séma Lambda kifejezéssel
A következő program bemutatja, hogyan lehet elvégezni a klasszikus visszahívási függvénysémát a lambda kifejezéssel:
#befoglalnisegítségével névtérórák;
char *Kimenet;
autocba= [](charki[])
{
Kimenet=ki;
};
üresmainFunc(charbemenet[],üres (*számára)(char[]))
{
(*számára)(bemenet);
költség<<'a fő funkcióhoz'<<' n';
}
üresfn()
{
költség<<'Most'<<' n';
}
intfő-()
{
charbemenet[] = 'visszahívási funkcióhoz';
mainFunc(bemenet, cba);
fn();
költség<<Kimenet<<' n';
Visszatérés 0;
}
A kimenet:
fő funkciójáhozMost
visszahívási funkcióhoz
Emlékezzünk vissza, hogy amikor egy lambda kifejezés definíciót hozzárendelünk egy változóhoz a globális hatókörben, annak függvényteste láthatja a globális változókat a rögzítési záradék alkalmazása nélkül.
A trailing-return típus
A lambda kifejezés visszatérési típusa automatikus, vagyis a fordító határozza meg a visszatérési típust a visszatérési kifejezésből (ha van). Ha a programozó valóban meg akarja adni a visszatérési típust, akkor ezt a következő program szerint fogja tenni:
#befoglalnisegítségével névtérórák;
autofn= [](intálljon meg) -> int
{
intválasz=álljon meg+ 3;
Visszatérésválasz;
};
intfő-()
{
autováltozó=fn(2);
költség <<változó<< ' n';
Visszatérés 0;
}
A kimenet 5. A paraméterlista után a nyíl operátor beírásra kerül. Ezt követi a visszatérési típus (ebben az esetben az int).
Bezárás
Tekintsük a következő kódrészletet:
strukCla{
intid= 5;
charch= 'nak nek';
}obj1, obj2;
Itt Cla a struktura osztály neve. Az Obj1 és az obj2 két olyan objektum, amelyek a struktura osztályból lesznek példányosítva. A Lambda kifejezés hasonló a megvalósításban. A lambda függvény definíció egyfajta osztály. Amikor a lambda függvényt meghívjuk (meghívjuk), egy objektum a példányából származik. Ezt az objektumot zárásnak nevezik. A zárás az, ami elvégzi a lambdától elvárt munkát.
Azonban a lambda kifejezésnek a fenti struktúrához hasonló kódolása esetén az obj1 és az obj2 helyére a megfelelő paraméterek argumentumai lépnek. Az alábbi program ezt szemlélteti:
#befoglalnisegítségével névtérórák;
autofn= [](intparam1,intparam2)
{
intválasz=param1+param2;
Visszatérésválasz;
} (2,3);
intfő-()
{
autoahol=fn;
költség <<ahol<< ' n';
Visszatérés 0;
}
A kimenet 5. Az argumentumok 2 és 3 zárójelben vannak. Vegye figyelembe, hogy a lambda kifejezés függvényhívása, az fn, nem fogad el érveket, mivel az argumentumok már a lambda függvénydefiníció végén vannak kódolva.
Következtetés
A lambda kifejezés névtelen függvény. Két részből áll: osztály és objektum. Meghatározása egyfajta osztály. A kifejezés meghívásakor egy objektum keletkezik a definícióból. Ezt az objektumot zárásnak nevezik. A zárás az, ami elvégzi a lambdától elvárt munkát.
Ahhoz, hogy a lambda kifejezés változót kapjon egy külső függvény hatókörből, nem üres rögzítési záradékra van szüksége a függvénytestébe.