een lange titel

C++11 Lambdafuncties

Lambdafuncties zijn een belangrijke aanvulling in C++11.

Lambda

In het volgende voorbeeld wordt het maximum in een lijst getallen gezocht. Er wordt gebruik gemaakt van lambdafuncties en STL.

Het voorbeeld loopt in 3 stappen:

  • max1()
  • max2()
  • max3()

Stap 1

Het accumulate() algoritme wordt toegepast. Dit algoritme start met 4 parameters.

  • de start van de lijst
  • het einde van de lijst
  • de startwaarde voor de accumulator van de lijst
  • de functie die voor elk element van de lijst uitgevoerd wordt

De functie krijgt twee parameters en heeft een returnwaarde.

  • de voorlopige accumulator
  • het huidige element
  • als return het nieuwe maximum

Stap 2

In deze stap zijn de elementen van het type Punt *, pointers naar Punt dus. De oproep van accumulate() is herschreven. Het maximum van x en van y wordt in twee stappen berekend. accumulate() wordt daarom tweemaal opgeroepen, telkens met een eigen lambdafunctie.

Stap 3

In deze stap wordt max3() geparametreerd met een lambdafunctie die gebruikt wordt om de juiste datamember van een Punt object op te halen. Deze parameter heet get en moet voorkomen in de capture van de interne lambdafunctie die het grootste getal bepaalt.

  • algo.cpp

Broncode: algo.cpp

#include <iostream>
#include <array>
#include <vector>
#include <algorithm>

void max1()
{
   std::array<int, 5> lijst {1, 4, 6, 8, 2};

   int maximum = 
   std::accumulate(lijst.begin(), lijst.end(), lijst[0], [](const int &a, const int &b)
   {
      if (b>a)
      {
         return b;
      }
      else
      {
         return a;
      }
   });

   std::cout << "max is " << maximum << std::endl;
}

class Punt
{
private:
   int x;
   int y;

public:
   Punt(int ix, int iy) : x(ix), y(iy)
   {
   }
   int getX()
   {
      return x;
   }
   int getY()
   {
      return y;
   }
};

void max2()
{
   std::vector<Punt *> lijst {new Punt(2,3), new Punt(4,1), new Punt(7,2) };

   int maximumx = 
   std::accumulate(lijst.begin(), lijst.end(), 
   lijst[0]->getX(), 
   [](const int &a, Punt *p)
   {
      int b = p->getX();
      if (b > a)
      {
         return b;
      }
      else
      {
         return a;
      }
   });

   std::cout << "max x is " << maximumx << std::endl;

   int maximumy = 
   std::accumulate(lijst.begin(), lijst.end(), 
   lijst[0]->getY(), 
   [](const int &a, Punt *p)
   {
      int b = p->getY();
      if (b > a)
      {
         return b;
      }
      else
      {
         return a;
      }
   });

   std::cout << "max y is " << maximumy << std::endl;
}

int max3(std::function<int(Punt*)> get)
{
   std::vector<Punt *> lijst {new Punt(2,3), new Punt(4,1), new Punt(7,2) };

   int maximum = 
   std::accumulate(lijst.begin(), lijst.end(), 
   get(lijst[0]), 
   [&get](const int &a, Punt *p)
   {
      int b = get(p);
      if (b > a)
      {
         return b;
      }
      else
      {
         return a;
      }
   });

   std::cout << "max is " << maximum << std::endl;
   return maximum;
}


int main()
{
   max1();
   max2();
   max3([](Punt *p) {return p->getX();});
   max3([](Punt *p) {return p->getY();});
   
   return 0;
}