Lambdas und bewusstes Einfangen von Werten
Eine Lambdaexpression erzeugt ein aufrufbares Objekt. Sie ist nützlich, wenn du eine kleine Funktion nur an einer Stelle brauchst, etwa als Auswahlkriterium für einen Algorithmus. Das erzeugte Objekt heißt Closure, auf Deutsch ungefähr Funktionsabschluss.
Lambdas und bewusstes Einfangen von Werten#
Modernes C++ · Lektion 44 von 60
Voraussetzungen: Algorithmen, Referenzen. Lernziel: Du formulierst kleine Funktionen direkt am Einsatzort.
Eine Lambdaexpression erzeugt ein aufrufbares Objekt. Sie ist nützlich, wenn du eine kleine Funktion nur an einer Stelle brauchst, etwa als Auswahlkriterium für einen Algorithmus. Das erzeugte Objekt heißt Closure, auf Deutsch ungefähr Funktionsabschluss.
1#include <algorithm>2#include <iostream>3#include <vector>4 5int main() {6 const std::vector<int> werte{2, 5, 8, 11};7 const int grenze{6};8 const auto anzahl = std::count_if(werte.begin(), werte.end(),9 [grenze](int wert) { return wert > grenze; });10 std::cout << anzahl << '\n';11}Die Ausgabe ist 2. count_if zählt Elemente, für die das übergebene Prädikat wahr liefert. Die Lambda nimmt einen Parameter wert und prüft ihn gegen grenze.
Aufbau einer Lambda#
Die eckigen Klammern sind die Capture-Liste, also die Auswahl eingefangener Werte aus der Umgebung. Runde Klammern enthalten die Parameter. Der Körper steht in {}. Ein optionales -> Typ kann den Rückgabetyp ausdrücklich festlegen, wenn du ihn nicht ableiten lassen möchtest.
[grenze] speichert hier eine Kopie. [&grenze] würde eine Referenz auf das Original verwenden. [] fängt nichts ein. [=] und [&] erlauben breite automatische Erfassung; ausdrücklich genannte Werte machen Abhängigkeiten oft besser sichtbar.
Die Lebensdauer zählt weiter#
Wenn eine Lambda später ausgeführt oder aus einer Funktion zurückgegeben wird, dürfen eingefangene Referenzen nicht auf schon zerstörte lokale Objekte zeigen. Auch ein eingefangener this-Zeiger hält das Klassenobjekt nicht am Leben.
Eine kopierte Variable ist standardmäßig nicht über die gewöhnliche Lambda-Aufruffunktion veränderbar. mutable erlaubt Änderungen an dieser gespeicherten Kopie. Das verändert weiterhin nicht automatisch die ursprüngliche Variable.
Callback und Funktionsobjekt#
Ein Callback ist eine aufrufbare Einheit, die du einer anderen Funktion zur späteren oder internen Verwendung übergibst. Eine Lambda ist eine Möglichkeit dafür. „Später“ kann innerhalb des unmittelbaren Algorithmusaufrufs oder erst nach dessen Rückkehr bedeuten; für Referenzen ist dieser Unterschied entscheidend.
Eine Lambda ohne Capture kann in passenden Situationen in einen Funktionszeiger umgewandelt werden. Eine Lambda mit gespeichertem Zustand passt nicht einfach in denselben gewöhnlichen Funktionszeigertyp.
Übung#
Was passiert bei [grenze], wenn die ursprüngliche veränderbare grenze nach Erzeugen der Lambda auf 100 gesetzt wird?
Lösung
Die eingefangene Kopie behält ihren bisherigen Wert. Bei Referenz-Capture würde die Lambda stattdessen auf das weiterhin lebende Original zugreifen.
Weiterlernen#
Zurück: Templates, Typvorlagen und Concepts · Kursübersicht · Weiter: Verschieben, std::move und Wertkategorien
Kommentare 0
Kommentare sind für diese Seite deaktiviert.