Tämä kurssi on jo päättynyt.

Lyhyt sivuraide: Lambdat C++ssa [](){}

Ohjelmointi 1:llä tai Johdatus ohjelmointiin -kurssilla esiteltiin Pythonissa lambda-funktiot eli pienet, nimettömät funktiot. Lambdan hyöty on tilanteissa, joissa tarvitaan pientä funktiota paikallisesti, mutta sille ei ole jatkokäyttöä. Lambda on erityisen kätevä kirjastoalgoritmien, esim. std::for_each kanssa. Myös Qt:n connect hyväksyy slotiksi lambdan.

../../_images/lambda_fi.png

Lambdaa voi verrata literaaliin. Otetaan perinteinen funktiomäärittely

int fun (int param) {
    return 2*param;
}

Vastaavasti sama toiminnallisuus saadaan lambdana [](int param){ return 2*param; } . Muuttujissa sama tilanne saadaan määrittelemällä int const var = 2;, jossa 2 vastaa lambdaa, kun taas koko määrittelyn voidaan ajatella vastaavan funktion nimettyä määrttelyä.

Esimerkkejä lambdasta:

std::vector<int> v (10, 0);
std::for_each(v.begin(), v.end(), [](int& elem){ ++elem });
std::vector<int> values;
int input = 0;
std::cin >> input;
auto iter = std::find_if( values.begin(), values.end(),
                          [input](int curr){ return ( input < curr ); });

Tutustutaan hiukan tarkemmin lambdan syntaksiin.

() parametrilista. Sisältää lambdan parametrit nimettyjen funktioiden tapaan.

-> lambdan paluuarvo. Paluuarvo voidaan jättää pois, jos se on void tai pääteltävissä lambdan koodista (pelkkä return-lause).

{} lambdan runko, joka voi olla miten monimutkainen tahansa. On kuitenkin järkevää pitää lambdat tiiviinä ja runko lyhyenä.

[] ns. capture kertoo lambdalle tietoa sen kontekstista eli auttaa lambdaa olemaan tietoinen ja vaikuttamaan ympäristöönsä. Lambdalle voi toki myös välittää parametreja, mutta koska lambdojen hyötykäyttökohteisiin kuuluvat algoritmit, ei parametreja voi määrätä täysin vapaasti. Kontekstista tarvittavien arvojen nappaaminen antaa lambdalle joko arvo- tai viitteenvälityksenä mahdollisuuden käyttää määrittelyalueessaan olevia olioita.

  • [&] nappaa kaikki lambdan käyttämät muuttujat viitteenvälityksellä
  • [& var] viitenappaus
  • [=] nappaa kaikki lambdan käyttämät muuttujat arvonvälityksellä
  • [&, var] nappaa muuttujan viitteenvältyksellä, paitsi var arvona
  • [=, &var] vastaavasti nappaa muuttujat arvonvälityksellä, paitsi var viittenä

Lambdan voi halutessaan ottaa myös talteen.

auto lambda = [&](int var){env = var;};

Tällöin tyyppinä pitää käyttää auto a, koska lambda on kääntäjän tuottama ja siten vain kääntäjä tietää sen tyypin.

Qt:n connect in uudessa syntaksissa voi lambdaa käyttää samoin kuin standardikirjaston algoritmien kanssa.

connect( sender, &Sender::valueChanged,
         receiver, &Receiver::updateValue);

connect( sender, &Sender::valueChanged,
 [=]( const QString &newValue ) { receiver->updateValue( "senderValue", newValue ); } );
Palautusta lähetetään...