Was ist die in C ++ 20 eingeführte Vorlage Lambda, wenn C ++ 14 bereits generisches Lambda enthält?


99

führte generische Lambdas ein, die es ermöglichten, Folgendes zu schreiben:

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

Es ist sehr klar, dass dieses generische Lambda funcgenau so funktioniert, wie eine Vorlagenfunktion funktionieren funcwürde.

Warum hat das C ++ - Komitee beschlossen, eine Vorlagensyntax für generisches Lamda hinzuzufügen?


5
Was ist, wenn Sie einen anderen Vorlagentyp als für die Argumente oder den Rückgabetyp verwenden müssen? Und was ist, wenn es im Körper gebraucht wird?
Einige Programmierer Typ

Mir wurde gesagt, dies sei ein interessanter Anwendungsfall.
Max Langhof

Antworten:


115

C ++ 14 generische Lambdas sind eine sehr coole Möglichkeit, einen Funktor mit einem folgenden Format zu generieren operator ():

template <class T, class U>
auto operator()(T t, U u) const;

Aber nicht so:

template <class T>
auto operator()(T t1, T t2) const; // Same type please

Noch so:

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

Auch nicht so (obwohl es etwas schwierig wird, es tatsächlich zu benutzen):

template <class T>
auto operator()() const; // No deduction

C ++ 14 Lambdas sind in Ordnung, aber mit C ++ 20 können wir diese Fälle problemlos implementieren.


2
Schön und prägnant. Fügen Sie einfach Folgendes hinzu: Der erste (gleiche Typ) kann (auto a, decltype(a) b)in C ++ 14 gelöst werden .
Sebastian Mach

13
@SebastianMach fast. Mit dieser Lösung bwird nicht abgeleitet, und ihr Argument wird implizit in den Typ von astattdessen konvertiert .
Quentin

32

Da Sie in C ++ 20 Lambdas mit Vorlagen verwenden können, können Sie Ihre Typen einfacher einschränken als mit einem SFINAE-Ausdruck:

auto lambda = []<typename T>(std::vector<T> t){};

Dieses Lambda funktioniert nur mit Vektortypen.


8
Wie hängt das constevalmit der neuen Syntax zusammen? Es ist cool und alles, aber ich verstehe die Relevanz nicht.
Geschichtenerzähler - Unslander Monica

Es ist eher eine Information darüber, was C ++ 20 zum Lambda-Ausdruck hinzufügt, als eine Antwort auf die Frage
Antoine Morrier

24

Der Vorschlag , der in C ++ 20 angenommen wurde, enthält einen langen Motivationsabschnitt mit Beispielen. Die Prämisse davon ist folgende:

Es gibt einige Hauptgründe, warum die aktuelle Syntax zur Definition generischer Lambdas vom Autor als unzureichend angesehen wird. Der Kern davon ist, dass einige Dinge, die mit normalen Funktionsvorlagen leicht erledigt werden können, ein erhebliches Reifenspringen erfordern, um mit generischen Lambdas ausgeführt zu werden, oder überhaupt nicht ausgeführt werden können. Der Autor ist der Ansicht, dass Lambdas wertvoll genug sind, dass C ++ sie unterstützen sollte genauso gut wie normale Funktionsvorlagen.

Daran schließen sich einige Beispiele an.


21

Die in C ++ 20 eingeführte neue "vertraute Vorlagensyntax" für Lambdas macht Konstrukte wie  for_types und  for_range lebensfähig und im Vergleich zu C ++ 17-Alternativen viel lesbarer.

(Quelle: Iteration zur Kompilierungszeit mit C ++ 20 Lambdas )

Eine weitere interessante Funktion, die sowohl für generische C ++ 14- als auch für C ++ 17-Lambdas ausgeführt werden kann, ist das direkte Aufrufen  operator() durch explizite Übergabe eines Vorlagenparameters:

C ++ 14:

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20:

  auto l = []<typename T>(){ };
  l.template operator()<int>();

Das obige C ++ 14-Beispiel ist ziemlich nutzlos: Es gibt keine Möglichkeit, auf den Typ zu verweisen, der  operator() im Hauptteil des Lambda angegeben ist, ohne dem Argument einen Namen zu geben und es zu verwenden  decltype. Außerdem müssen wir ein Argument übergeben, obwohl wir es möglicherweise nicht benötigen.

Das C ++ 20-Beispiel zeigt, wie T im Körper des Lambda leicht zugänglich ist und dass ein Null-Lambda nun willkürlich als Vorlage verwendet werden kann. Dies wird für die Implementierung der oben genannten Konstrukte zur Kompilierungszeit sehr nützlich sein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.