Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

C++ Grundkurs

Was sind Lambda-Funktionen?

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Die aktuellen Versionen von C++ verfügen inzwischen ebenfalls über Lambda-Funktionen. Diese stellen ein leistungsstarkes Werkzeug dar und dienen dazu, den Quellcode deutlich lesbarer zu gestalten.
08:29

Transkript

In dieser Lektion will ich Ihnen Lambda-Funktionen in C++ vorstellen. Bevor ich aber auf Lambda-Funktionen eingehe, will ich Ihnen erst mal kurz erläutern, woher Lambda-Funktionen kommen. Lambda-Funktionen kommen aus der funktionalen Programmierung. Das ist ein Konzept, das schon seit den 60er Jahren bekannt ist. Sie etablieren sich mittlerweile auch in den klassischen Programmiersprachen. So besitzt C++, Java oder auch Python Lambda-Funktionen. Wieso Lambda-Funktionen so wichtig in den etablierten Programmier- sprachen werden, hängt mit der einfachen Tatsache zusammen, dass sie enorm praktisch und sehr mächtig sind. Aber was sind nun Lambda-Funktionen? Lambda-Funktionen sind Funktionen ohne Namen. Sie können ihre Funktionalität an Ort und Stelle definieren und ausführen. Sie können wie Daten kopiert werden und sie können auch ihren Aufrufkontext speichern. In diesem Fall nennt man sie dann Clousers. Noch zwei Regeln zum Einsatz von Lambda-Funktionen. Lambda-Funktionen sollen kurz und knackig sein und sie sollen selbsterklärend sein. Selbsterklärende sein heißt, wenn Sie eine Lambda-Funktionen schreiben, für die sie extrem viel Kommentar benötigen, um diese Lambda-Funktionen zu erklären bzw. das zu erklären, was die Lambda-Funktionen tut, haben Sie vermutlich was falsch gemacht. Jetzt will ich Ihnen die Syntax von Lambda-Funktionen noch ein bisschen genauer vorstellen. Hier sehen Sie die Syntax von Lambda-Funktionen. Lambda-Funktionen bestehen aus vier Teilen. Durch die eckigen Klammern wird die Lambda-Funktion eingeleitet. Hier können Sie spezifizieren, wie Sie sich an den Aufrufkontext binden. Dann folgen die Parameter, wie bei einer normalen Funktion. Diese Klammern sind optional. Das heißt, wenn Ihre Lambda-Funktion keine Parameter hat, benötigen Sie auch keine runden Klammern. Dann folgt genauso optional die Angabe des Rückgabetyps. Optional heißt, wenn die Lambda-Funktion hinreichend einfach ist, wenn sie nur aus einem tursten-Statement zum Beispiel besteht, ist die Angabe des Rückgabetyps nicht notwendig. Das kann der Compiler selber rausfinden. Hier folgt der function body, wie bei einer normalen Funktion. Wenn Sie sich das in Ruhe anschauen, stellen Sie fest, das schaut eigentlich nicht anders aus wie eine normale Funktion, nur eben der alternativen Funktionssyntax. Jetzt habe ich Ihnen die Theorie rund um Lambda-Funktionen ein wenig erklärt. Jetzt will ich es Ihnen natürlich noch in der Anwendung zeigen. Hier habe ich ein paar Beispiele. Damit es möglichst anschaulich ist, habe ich Lambda-Funktionen mit Funktionen und Funktionsobjekten in diesem Beispiel verglichen. Mein Ziel in dem Beispiel ist, einen Vektor, den sehen Sie hier, der Strings beinhaltet, zu sortieren. Sie sehen, ich initialisiere den Vektor mit diesen Strings und ich verwende hier den Algorithmus der Standard Template Library. Der heißt std::sort und sortiert den Vektor von myStrVec.begin bis myStrVec.end und wendet das Sortierkriterium lessLength an. Also nach der kleineren Länge soll das sortiert werden. lesslength ist ein Funktions-Pointer und hier sehen Sie, wie ich die Funktion definiert habe. Die erwartet zwei Konstante als Stringreferenzen f und s und gibt als Ergebnis zurück, welcher der beiden Strings kleiner ist und das ist das Sortierkriterium. Wenn ich jetzt std::sort anwende, sehen Sie, die Strings sind sortiert in aufsteigender Reihenfolge. Zur Ausgabe verwende ich hier die bekannte range-basierte for-Schleife. Jetzt sortiere ich den Vektor noch einmal. Diesmal sortiere ich ihn aber nicht aufsteigend, sondern absteigend. Jetzt verwende ich auch als Sortierkriterium ein Funktionsobjekt. Das ist das Teil hier. GreaterLength ist ein Funktionsobjekt, ist eine Instanz einer Klasse, die ich hier in-place instanziiere. Jetzt zeige ich Ihnen das Funktionsobjekt GreaterLength. Das sehen Sie hier. Das ist eine Klasse, für die der Klammeroperator überladen ist. Sie sehen es, diese Klammern hier. Das heißt, das ist eine Klasse, wenn ich ein Objekt von dieser Klasse instanziiere, verhält sich ein Objekt dieser Klasse wie eine Funktion. Ich kann sie also wie eine Funktion aufrufen. Besonders ist aber, weil sie eine Klasse hat, kann sie einen Zustand besitzen. Das benötigt man hier nicht, aber sie kann es prinzipiell trotzdem. Wenn Sie sich die Signatur dieser Methode anschauen, stellen Sie fest, die ist identisch zu der Signatur von der Funktion hier oben. Sie ist const. Das ist der einzige Unterschied, aber sie macht das Gleiche. Sie ermittelt, ob Length größer von f, größer wie Length von s ist. Diesmal aber größer im Gegensatz zu oben kleiner. Ich werde diese Strings von größer nach kleiner sortieren. Wende ich das Funktionsobjekt an, nachdem ich es hier instanziiert habe, sehen Sie, der Vektor ist nun von kleiner nach größer sortiert. Jetzt geht es weiter mit einer Lambda-Funktion. Wie gesagt, die Lambda-Funktion erlaubt es Ihnen die Funktionalität an Ort und Stelle zu definieren. Ich verwende keine Funktion, auf die ich die mir einen Funktions-Pointer verweisen muss. Ich verwende kein Funktionsobjekt, das ich instanziieren muss und das sich irgendwo anders befindet. Ich verwende eine Lambda-Funktion und schreibe die genau dorthin, wo ich sie brauche. Jetzt schaue ich mir mit Ihnen die Lambda-Funktion an. Hier wird die Lambda-Funktion eingeleitet. Das sind die Argumente der Lambda-Funktion. Diese Argumente sind genau gleich wie die Argumente des Funktionsobjekts oder die Argumente der Funktion. Den Funktionskörper kennen Sie. Ich sortiere diesmal wieder aufsteigend. f.length < s.length. Das Ergebnis kennen Sie natürlich auch. Das sehen Sie hier wieder. Man kann aber mit Lambda-Funktionen noch viel mehr machen. Ich zeige Ihnen ein weiteres Beispiel. Ich könnte auch die Lambda-Funktion verwenden, um die Elemente meines Strings mit der Lambda-Funktion auszugeben im Gegensatz zu hier oben, wo ich eine range-basierte for-Schleife verwendet habe. Das mache ich hier. Dazu wende ich den Algorithmus std::for_each an. std::for_each iteriert über jedes Element des Vektors, den er hat, in diesem Fall von begin bis end jedes Element. Das schnappe ich mir hier und in diesem Fall, das tue ich für jedes Element, ich gebe jedes Element auf die Konsole aus. In diesem Fall, um einen kleinen Unterschied zu haben, mit Komma separiert. Also noch einmal std::for_each geht von myStrVec.begin bis myStrVec.end und wendet auf jedes Element diese kleine Lambda-Funktion an und diese kleine Lambda-Funktion gibt einfach jedes Element aus gefolgt von einem Komma. Aus diesem Grund sehen Sie bei dieser Ausgabe auch Kommata. Zu diesem std::for_each Algorithmus will ich Ihnen zwei Beispiele zeigen. Aus dem Grund will ich Sie Ihnen auch zeigen, um Ihnen noch ein Beispiel dafür zu geben, wie praktisch Lambda-Funktionen sind. Dazu scrolle ich ein bisschen runter. Jetzt habe ich einen Vektor von ints. Sie sehen myVec1{1, 2, 3, 4, 5, 6, 7, 8, 9,10}, den ich über eine Initialisiererliste initialisiere. Was will ich machen? Ich will jedes Element auf sein Quadrat abbilden. Ich will aus 1 1 machen, aus 2 4, aus 3 9, aus 5 16 usw. Wie mache ich das? Ich sage wieder, wende auf jedes Element an, also std::for_each myVec1.begin(), myVec1.end() und was ich anwende in diesem Fall, ist, dass ich i auf i * i abbilde, also quadriere. Noch ein interessanter Punkt. Um die Elemente des Vektors zu modifizieren, muss ich sie natürlich per Referenz annehmen. Aber das sind die normalen Regeln, die Sie auch von Funktionen kennen. Wenn Sie das jetzt hier anschauen, sehen Sie, der Algorithmus tut genau das, was er versprochen hat. Er quadriert jedes Element. Noch eine kleine Variation. Diesmal nehme ich einen Vektor von doubles wieder mit den Elementen 1 bis 10. Jetzt gehe ich über den ganzen Vektor, also von begin bis end. Was mache ich? In diesem Fall wende ich die Wurzelfunktion an. Ich bilde also jedes Element des Vektors auf seine Wurzel ab. Die Ausgabe sehen Sie hier. Die Wurzel aus 1 ist 1, aus 2 ist 1.41, aus 3 ist 1.73, aus 4 ist dann wiederum relativ einfach. Das ist die 2 usw. Damit die Ausgabe schön ist, habe ich ein bisschen die Ausgabe manipuliert, indem ich das flag std::fixed gesetzt habe. Damit ich keine exponential Schreibweise habe und indem ich die Hinterkommaanzahl auf 2 definiert habe. So sehen Sie, das ist die Ausgabe. In dieser Lektion habe ich Ihnen Lambda-Funktionen vorgestellt. Lambda-Funktionen, die ein mächtiges Konzept aus der funktionalen Programmierung sind und mittlerweile Einzug halten in den etablierten Programmiersprachen. Lambda-Funktionen, das sind meine zwei Regeln, sollen kurz und knackig sein und sie sollen selbsterklärend sein.

C++ Grundkurs

Steigen Sie in die mächtige Programmiersprache C++ ein und lernen Sie dabei alle wichtigen Funktionen mit Anwendungsbeispielen kennen.

8 Std. 14 min (147 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!