Funktionale Programmierung in C++: Von Lambdas bis zu Algorithmen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Funktionale Programmierung in C++: Von Lambdas zur Komposition



Funktionale Programmierung (FP) ist ein Paradigma, bei dem Berechnungen auf der Anwendung reiner Funktionen, Datenunveränderlichkeit und der Abwesenheit von Seiteneffekten basieren. Obwohl C++ ursprünglich eine multiparadigmatische Sprache war, haben seine modernen Standards (C++11/14/17/20) leistungsstarke Werkzeuge für FP eingeführt: Lambda-Ausdrücke, std::function, STL-Algorithmen, Coroutinen und sogar Unterstützung für monadische Muster. In diesem Artikel werden wir untersuchen, wie man funktionalen Code in C++ schreibt, ohne Leistung einzubüßen.



1. Grundlagen des funktionalen Stils: Lambdas und std::function



Lambda-Ausdrücke sind das Herzstück von FP in C++. Sie ermöglichen es, anonyme Funktionen "im Handumdrehen" zu erstellen, wobei der Kontext erfasst wird.



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

int main() { std::vector<int> nums = {1, 2, 3, 4, 5}; // Lambda zum Filtern gerader Zahlen auto is_even = [](int x) { return x % 2 == 0; }; // Verwendung mit dem std::copy_if-Algorithmus std::vector<int> evens; std::copy_if(nums.begin(), nums.end(), std::back_inserter(evens), is_even); for (int n : evens) std::cout << n << " "; // 2 4 return 0;}


Wichtige Punkte zu Lambdas:

  • Capture — [=] (by value), [&] (by reference), [this] (für Klassenmethoden).
  • Typ — jedes Lambda hat einen eindeutigen Typ, daher werden std::function oder Templates verwendet, um sie an Funktionen zu übergeben.
  • Rückgabewert — wird automatisch abgeleitet, sofern nicht anders angegeben.


std::function — ein Wrapper für aufrufbare Objekte (Funktionen, Lambdas, Funktoren). Es ist praktisch für die Speicherung und Übergabe, fügt aber Overhead hinzu (virtueller Aufruf).



#include <functional>

void apply_twice(std::function<int(int)> f, int x) { std::cout << f(f(x)) << std::endl; // Komposition}

int main() { auto square = [](int x) { return x * x; }; apply_twice(square, 3); // (3^2)^2 = 81 return 0;}


2. STL-Algorithmen als Grundlage funktionaler Ketten



STL-Algorithmen (std::transform, std::copy_if, std::accumulate usw.) passen perfekt in den funktionalen Stil. Sie modifizieren Container nicht direkt, sondern nehmen Iteratoren entgegen und geben Ergebnisse zurück.



Beispiel: Filtern und Transformation (map/filter)



#include <numeric>#include <ranges> // C++20

int main() { std::vector<int> data = {1, 2, 3, 4, 5, 6}; // Klassischer Ansatz (C++11) std::vector<int> filtered; std::copy_if(data.begin(), data.end(), std::back_inserter(filtered), [](int x) { return x > 3; }); std::vector<int> result; std::transform(filtered.begin(), filtered.end(), std::back_inserter(result), [](int x) { return x * 2; }); // Moderner Ansatz mit ranges (C++20) auto view = data | std::views::filter([](int x) { return x > 3; }) | std::views::transform([](int x) { return x * 2; }); for (int v : view) std::cout << v << " "; // 8 10 12 return 0;}


Fold mit std::accumulate



#include <numeric>

int main() { std::vector<int> nums = {1, 2, 3, 4}; // Summe mit Startwert 0 int sum = std::accumulate(nums.begin(), nums.end(), 0, [](int a, int b) { return a + b; }); // Produkt mit Startwert 1 int prod = std::acc

Blogs

Buchempfehlungen