namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:lambda

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


kennen:lambda [2020-07-27 09:52] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Lambda-Ausdrücke ======
 +
 +> // Aus diesem Grunde kratzen die folgenden Beispiele nur an der Oberfläche. //
 +> // Andererseits können wir nur an der Oberfläche kratzen, denn wenn wir tiefer kratzen, sind wir nicht mehr an der Oberfläche. //
 +>>  --- Lawrence J. Peter
 +
 +===== Ad-hoc-Funktionen =====
 +[[..:kennen:include:algorithm|Algorithmen der Standard-Bibliothek]] wie 
 +[[..:kennen:lib:for_each|for_each()]] 
 +erwarten oft eine Funktion oder einen Funktor, der auf Elemente eines Bereichs angewendet wird. 
 +Mit einem Lambda-Ausdruck kann diese Funktion an Ort und Stelle erzeugt werden:
 +<code cpp>
 +#include <algorithm>
 +#include <iostream>
 +#include <string>
 +
 +void lambdademo()
 +{
 +  std::string s = "Hello, Lambda Expressions in C++11!";
 +
 +  std::for_each(s.begin(), s.end(),
 +    [] (char c) { std::cout << c; }       // <-- hier
 +  );
 +  std::cout << std::endl;
 +}
 +</code>
 +Lambdas sind anonyme, lokal definierte Funktionen. 
 +Der Rückgabetyp wird, sofern möglich, automatisch ermittelt. 
 +Er kann hinter der Parameterliste mit ''%%-> Zieltyp%%'' angegeben werden.
 +<code cpp>
 +  std::string uppercase;
 +  std::copy_if(s.begin(), s.end(), 
 +    std::back_inserter(uppercase), 
 +    [] (char c) -> bool
 +    { 
 +      return ('A' <= c && c <= 'Z'); 
 +    }
 +  );
 +  std::cout << uppercase << std::endl;
 +</code>
 +Man beachte den neuen Algorithmus ''copy_if()'' in ''<algorithm>''
 +
 +Lambdas sind als Variablenwerte speicherbar, um sie mehrfach zu nutzen. 
 +Das Schlüsselwort [[kennen:beispiel:auto]] ist hierbei hilfreich:
 +<code cpp>
 +  auto fromAtoZ = [] (char c) -> char
 +    { 
 +      return ('A' <= c && c <= 'Z') ? c : '.'; 
 +    };
 +
 +  std::list<char> aList;
 +  std::transform(s.begin(), s.end(), std::back_inserter(aList), fromAtoZ);
 +
 +</code>
 +
 +===== Closure =====
 +Lambda-Ausdrücke beginnen mit einer eckigen Klammer. 
 +In dieser kann angegeben werden, welche lokalen Variablen(werte) 
 +der Umgebung innerhalb des Lambda-Ausdrucks bekannt sein sollen. 
 +Dieses Einbeziehen der Umgebung wird Closure (Einschluss) genannt.
 +<code cpp>
 +#include <algorithm>
 +#include <iostream>
 +#include <vector>
 +#include <string>
 +
 +void closuredemo()
 +{
 +  std::string s = "Hello, lambda expressions in C++11!";
 +  char low = 'A', high = 'Z';
 +
 +  std::for_each(s.begin(), s.end(),
 +    [low, high] (char c)            // closure by value
 +    { 
 +      if (low <= c && c <= high) std::cout << c; 
 +    }
 +  ); 
 +  std::cout << std::endl;
 +}
 +</code>
 +Hier werden die bei der Lambda-Definition aktuellen Werte der Variablen ''low'' und ''high'' übernommen. 
 +Auch referenzieller Einschluss ist möglich und manchmal erwünscht:
 +<code cpp>
 +  int count = 0;
 +  std::for_each(s.begin(), s.end(),
 +    [low, high, &count] (char c)    // closure by reference: &count 
 +    { 
 +      if (low <= c && c <= high) ++count; 
 +    }
 +  );
 +  std::cout << count << std::endl;
 +</code>
 +Durch die Angabe ''[&]'' werden alle Variablen der Umgebung als Referenz übernommen. 
 +Durch ''[=]'' werden alle Werte der Umgebung kopiert. 
 +Auch gemischte Angaben ''[=, &count]'' sind möglich. 
 +In Methoden definierte Lambdas können ''[this]'' (als Wert) einschließen, 
 +um an Attribute eines Objektes heranzukommen.
 +Weitere Beispiele sind im 
 +[[http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx |Visual Team Blog]] 
 +zu finden.
 +
 +===== Lambda-capture-Ausdrücke =====
 +C++14 erlaubt bei der Definition des Lambda-Ausdrucks neue lokale Variablen einzuführen, die ihre Werte durch Ausdrücke erhalten:
 +<code cpp>
 +void tabulate(double a, double b, int n)
 +{
 +  auto f = [a, dy = (b-a)/n] (int i) { return a + i * dy; };
 +
 +  for (int i = 0; i <= n; ++i)
 +  {
 +    std::cout << i << '\t' <<  f(i) << '\n';
 +  }
 +}
 +</code>
 +===== Generische Lambda-Ausdrücke =====
 +Der Typ von Lambda-Parametern kann vom Compiler ermittelt werden (ab [[kennen:begriffe#C++14]]):
 +
 +<code cpp>
 +void generic_demo()
 +{
 +  std::vector<std::string> v { "generic", "lambdas", "in", "C++14" };
 +
 +  std::sort(v.begin(), v.end(), [](auto a, auto b) { return a.size() < b.size(); });
 +
 +  for (auto e : v) std::cout << e << ' ';
 +  std::cout << '\n';
 +}
 +</code>
  

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki