variable - Was ist der Bedarf an Template Lambda, das in C++ 20 eingeführt wurde, wenn C++ 14 bereits generisches Lambda enthält?




std::function (3)

Die in C ++ 20 eingeführte neue "vertraute Template-Syntax" für Lambdas macht Konstrukte wie for_types und for_range Vergleich zu C ++ 17-Alternativen praktikabler und besser lesbar.

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

Eine weitere interessante Funktion, die sowohl für generische C ++ 14- als auch C ++ 17-Lambdas ausgeführt werden kann, ist der direkte Aufruf von operator() indem explizit ein Template-Parameter übergeben wird:

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 völlig nutzlos: Es gibt keine Möglichkeit, auf den für operator() bereitgestellten Typ im Lambda-Body zu verweisen, ohne dem Argument einen Namen zu geben und decltype . Außerdem sind wir gezwungen, ein Argument zu übergeben, obwohl wir es möglicherweise nicht benötigen.

Das C ++ 20-Beispiel zeigt, wie leicht T im Körper des Lambdas 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

Mit c ++ 14 wurden generische Lambdas eingeführt, mit denen Folgendes geschrieben werden konnte:

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

Es ist sehr klar, dass diese generische Lambda-Funktion genauso funktioniert wie eine Funktion mit Vorlagen.

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


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

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 ein bisschen 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.


Der proposal , der in C ++ 20 aufgenommen wurde, enthält einen langen Motivationsabschnitt mit Beispielen. Die Voraussetzung dafür ist:

Es gibt einige Hauptgründe, warum die aktuelle Syntax zur Definition von generischen Lambdas vom Autor als unzureichend erachtet wird. Das Wesentliche dabei ist, dass einige Dinge, die mit normalen Funktionsschablonen leicht gemacht werden können, einen erheblichen Sprung erfordern, um mit generischen Lambdas gemacht zu werden, oder überhaupt nicht. Der Autor ist der Meinung, dass Lambdas wertvoll genug sind, dass C ++ sie unterstützen sollte genauso gut wie normale Funktionsvorlagen.

Nachfolgend einige Beispiele.





generic-lambda