Rekursive Lambda-Funktion in C++

Saad Aslam 12 Oktober 2023
  1. C++ Rekursive Lambda-Funktion
  2. C++ Rekursive Lambda-Funktion mit std::function
  3. C++ Rekursive Lambda-Funktion mit Generic Lambda
  4. C++ Rekursive Lambda-Funktion mit y_combinator
Rekursive Lambda-Funktion in C++

In diesem Artikel werden wir die in C++ verfügbaren rekursiven Lambdas verstehen.

C++ Rekursive Lambda-Funktion

Rekursion bezieht sich auf einen Prozess, durch den eine Funktion (direkt oder indirekt) sich selbst aufruft, und die diesem Prozess entsprechende Funktion wird als rekursive Funktion bezeichnet. Das Ergebnis dieses Prozesses ist ein rekursiver Lambda-Ausdruck.

Wenn einige Probleme mit einer rekursiven Methode angegangen werden, sind sie viel einfacher zu lösen.

Bei der Umstrukturierung von lokalem Code sind Lambdas ein hilfreiches Werkzeug. Andererseits gibt es Fälle, in denen wir das Lambda aus sich selbst heraus verwenden möchten.

Dies kann aus einem von zwei Gründen erfolgen: um eine direkte Rekursion zu ermöglichen oder um es zu ermöglichen, dass die Schließung als Fortsetzung registriert wird. Die aktuelle Version von C++ macht es extrem schwierig, diese Aufgabe erfolgreich durchzuführen.

Implementierung der rekursiven Lambda-Funktion in C++

Im ersten Schritt importieren wir die notwendigen Bibliotheken.

#include <functional>
#include <iostream>

Initialisieren Sie innerhalb der Funktion main() eine Variable vom Typ int und weisen Sie ihr einen ganzzahligen Wert zu.

int main() { int anyNumber = 456789; }

Erstellen Sie dann eine Funktion vom Typ void und geben Sie ihr den Namen reverseByRecursiveLambda.

function<void()> reverseByRecursiveLambda;

Initialisieren Sie nun die Funktion reverseByRecursiveLambda mit einer rekursiven Lambda-Funktion.

reverseByRecursiveLambda = [&]() {};

Innerhalb dieser Methode sollten Sie eine Prüfung implementieren, die besagt, dass Sie nichts zurückgeben sollten, wenn der Integer-Wert von anyNumber gleich 0 ist. Wenn dies nicht der Fall ist, sollte die Funktion mit dem nächsten Satz von Operationen fortfahren.

Dann führt die Funktion eine Reihe von mathematischen Berechnungen durch, nach denen sie die Ergebnisse ausgibt. Als letzten Schritt wird die Funktion namens reverseByRecursiveLambda() erneut ausgeführt.

if (anyNumber == 0) return;

cout << anyNumber % 10 << " ";
anyNumber /= 10;
reverseByRecursiveLambda();

Nachdem diese Funktion die Ausführung abgeschlossen hat, ist das Einzige, was erforderlich ist, ein Aufruf dieser Funktion innerhalb der Methode main().

int main() { reverseByRecursiveLambda(); }

Vollständiger Quellcode:

#include <functional>
#include <iostream>

using namespace std;

int main() {
  int anyNumber = 123456789;

  function<void()> reverseByRecursiveLambda;

  reverseByRecursiveLambda = [&]() {
    if (anyNumber == 0) return;

    cout << anyNumber % 10 << " ";
    anyNumber /= 10;
    reverseByRecursiveLambda();
  };

  reverseByRecursiveLambda();
}

Ausgang:

9 8 7 6 5 4 3 2 1

C++ Rekursive Lambda-Funktion mit std::function

Das Klassen-Template std::function ist ein polymorpher Funktions-Wrapper, der für verschiedene Zwecke verwendet werden kann. Alle Lambda-Ausdrücke, Bindungsausdrücke oder andere Funktionsobjekte können innerhalb von Instanzen der Klasse std::function gespeichert, kopiert und aufgerufen werden.

Darüber hinaus können diese Instanzen Zeiger auf Elementfunktionen und Zeiger auf Datenelemente enthalten.

Im folgenden Beispiel müssen wir einen Schnappschuss der Fakultät erstellen, danach können wir sie im Lambda-Körper referenzieren.

Beispielcode:

#include <functional>
#include <iostream>

int main() {
  const std::function<int(int)> factorial = [&factorial](int n) {
    return n > 1 ? n * factorial(n - 1) : 1;
  };

  std::cout << "The factorial of 5 is: " << factorial(5);
  return factorial(5);
}

Ausgang:

The factorial of 5 is: 120

C++ Rekursive Lambda-Funktion mit Generic Lambda

Generic Lambda Expression bezieht sich auf einen Lambda-Ausdruck mit mindestens einem Argument vom Typ auto.

Die Verwendung von std::function ist nicht erforderlich, um rekursive Lambda-Funktionen zu erstellen, dank des generischen Lambda-Ausdrucks, der diese Option ermöglichte. Der Typ eines Lambda-Ausdrucks kann nicht allein durch seinen Namen bestimmt werden.

Daher musste vor der Veröffentlichung von C++14 ein rekursiver Lambda-Ausdruck in eine std::function eingeschlossen werden. Es ist nicht von std::function abhängig und muss keine Daten erfassen, um auf einem beliebigen numerischen Basistyp ordnungsgemäß zu funktionieren.

Im Beispiel demonstrieren wir, wie die in einer map gespeicherten Daten mit dem generischen Lambda auto angezeigt werden.

Beispielcode:

#include <algorithm>
#include <iostream>
#include <map>
#include <string>

int main() {
  const std::map<std::string, int> numbers{
      {"Saad", 22}, {"Zaryab", 23}, {"Zeeshan", 24}};

  std::for_each(std::begin(numbers), std::end(numbers), [](const auto& entry) {
    std::cout << "Name: " << entry.first << "   Age: " << entry.second << '\n';
  });
}

GCC 11.1.0 ist der Name des Compilers, der in dieser Demonstration verwendet wird.

Ausgang:

Name: Saad   Age: 22
Name: Zaryab   Age: 23
Name: Zeeshan   Age: 24

C++ Rekursive Lambda-Funktion mit y_combinator

Da anonyme Funktionen (auch bekannt als Lambdas) nur verwendet werden sollen, wenn die Logik unkompliziert ist und in eine benannte Funktion extrahiert werden soll, ist es unwahrscheinlich, dass ein rekursiver Aufruf innerhalb eines Lambdas erfolgt.

Stellen wir uns jedoch vor, dass wir keine Rekursion verwenden können. Solange Funktionen in unserer Sprache als erstklassige Bürger behandelt werden (sie können Variablen zugewiesen, als Argumente geliefert und wie jedes andere Objekt zurückgegeben werden), können wir immer noch unsere Rekursionsimplementierung schreiben.

Der Y-Kombinator ist für diesen Zweck eine nützliche Funktion höherer Ordnung. Trotz seines ominös klingenden Namens ist es nur eine Funktion höherer Ordnung, eine Funktion, die eine andere Funktion umschließt.

Das Folgende ist ein Beispiel für die Erstellung einer rekursiven Lambda-Funktion mit dem y-Kombinator, um die Fibonacci-Reihe aufzulisten.

Beispielcode:

#include <iostream>

template <typename Function>
struct YCombinator {
  Function yFunction;

  template <typename... Args>
  decltype(auto) operator()(Args&&... args) {
    return yFunction(*this, std::forward<Args>(args)...);
  }
};

template <typename Function>
decltype(auto) make_YCombinator(Function f) {
  return YCombinator<Function>{f};
}

int main() {
  auto fib = make_YCombinator([](auto self, int n) {
    if (n < 2) return 1;
    return self(n - 1) + self(n - 2);
  });

  for (int i = 0; i < 10; ++i)
    std::cout << "fib(" << i << ") = " << fib(i) << "\n";

  return 0;
}

GCC 11.1.0 ist der Name des Compilers, der in dieser Demonstration verwendet wird.

Ausgang:

fib(0) = 1
fib(1) = 1
fib(2) = 2
fib(3) = 3
fib(4) = 5
fib(5) = 8
fib(6) = 13
fib(7) = 21
fib(8) = 34
fib(9) = 55
Autor: Saad Aslam
Saad Aslam avatar Saad Aslam avatar

I'm a Flutter application developer with 1 year of professional experience in the field. I've created applications for both, android and iOS using AWS and Firebase, as the backend. I've written articles relating to the theoretical and problem-solving aspects of C, C++, and C#. I'm currently enrolled in an undergraduate program for Information Technology.

LinkedIn

Verwandter Artikel - C++ Lambda