opublikował: Razi91, 2014-03-09

Co to jest?

C++11 jest wyposażony w dość bogatą bibliotekę algorytmów (http://www.cplusplus.com/reference/algorithm/), dla zachowania uniwersalności (nie tylko na typach prostych się operuje) wiele z nich do działania potrzebuje funktorów. Funktory z kolei to klasy, które trzeba osobno stworzyć, nawet jeśli mają być zastosowane tylko raz. Funkcje lambda rozwiązują tę niedogodność pozwalając zrobić to w jednej linijce kodu.

Funkcje lambda mogą coś zwracać, typ jest dedukowany przez kompilator podczas kompilacji.

Typ lambdy i używanie jej

Lambdę można więc przetrzymywać w normalnej zmiennej i przekazywać do funkcji przez argumenty. Zachowuje się dokładnie tak jak obiekt klasy function, jest więc jakby funktorem i wywołuje się dokładnie tak samo jak funkcje:

  int big = bigger(a, b);

Jeśli chcemy napisać funkcję przyjmującą lambdę, trzeba ją dokładnie opisać:

  bool isNot(int a, int b, std::function<bool(int,int)> fun){
    return !fun(a,b);
  }

Zakres lambd, przechwytywane symbole

Symbole podajemy kolejno po przecinkach, przy czym:

  • [foo] — przekaż foo po wartości (wartość jest skopiowana)
  • [&foo] — przekaż foo po referencji (symbol przekazany po referencji)
  • [this] — wskaźnik this
  • [&] — automatycznie wszystkie użyte symbole w ciele lambdy (kompilator sam sprawdza które) po referencji
  • [=] — automatycznie wszystkie użyte symbole w ciele lambdy po wartości

Weźmy przykładowy wektor na którym będziemy operować:

  std::vector<int> foo={1,2,6,4,0,3};

Przemnożenie

Pętla ta przemnoży wszystkie komórki przez mul. Każdy element kolekcji przekazany będzie do lambdy przez referencję (int &v), a sam mnożnik przechwycony przez lambdę [&].

Wypisanie zawartości

  std::for_each(foo.begin(), foo.end(), [](int v){std::cout<<v;});

Sortować można nie tylko rosnąco lub malejąco, można też chcieć posortować tak, aby najpierw były parzyste, potem nieparzyste. Wymaga to innej funkcji niż samego operatora porównania. Można do tego wykorzystać algorytm sort:

  std::sort(od, do, funkcja(int,int))

Ciało funkcji nie musi składać się z tylko jednej operacji, przykładowo jakbyśmy chcieli posortować wektor stosując dwa kryteria: parzystość i wartość, można zrobić to w taki sam sposób, w jaki zrobiłoby się to w sposób tradycyjny:

  std::sort(foo.begin(), foo.end(), [](int a, int b){
    int ap = a%2;
    int bp = b%2;
    if(ap!=bp)
      return ap>bp;
    return a<b;
  });

Zaloguj się aby dodać komentarz