Freigeben über


Lambda-Ausdruckssyntax

Dieses Thema beschreibt die Syntax für Lambda-Ausdrücke.Es enthält ein Beispiel, das die strukturellen Elemente eines Lambda-Ausdruck und wie diese Elemente auf das Beispiel veranschaulicht.

Das folgende Programm verwendet Lambda-Ausdrücke mit zwei STL-Algorithmen: generate_n und for_each.Der Lambda-Ausdruck, der im Aufruf der generate_n Funktion weist ein Element der ein vector Objekt, das die Summe aus den vorherigen beiden Elementen.Der Lambda-Ausdruck, der im Aufruf der for_each Funktion druckt ein Element des gleichen vector Objekt in der Konsole.

// lambda_structure.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// The number of elements in the vector.
const int elementCount = 9;

int main() 
{
   // Create a vector object with each element set to 1.
   vector<int> v(elementCount, 1);

   // These variables hold the previous two elements of the vector.
   int x = 1;
   int y = 1;

   // Assign each element in the vector to the sum of the 
   // previous two elements.
   generate_n(v.begin() + 2, elementCount - 2, [=]() mutable throw() -> int {
      
      // Generate current value.
      int n = x + y;

      // Update previous two values.
      x = y;
      y = n;

      return n;
   });

   // Print the contents of the vector.
   for_each(v.begin(), v.end(), [](int n) { cout << n << " "; });
   cout << endl;

   // Print the local variables x and y.
   // The values of x and y hold their initial values because 
   // they are captured by value.
   cout << x << " " << y << endl;
}

Weitere Informationen zu den generate_n funktionieren, finden Sie unter generate_n.Weitere Informationen zu den for_each funktionieren, finden Sie unter for_each.

In den folgenden Abschnitten beschreiben die Grammatik eines Lambda-Ausdruck und wie jedes Element auf das vorherige Beispiel bezieht.

Lambda-Ausdruck-Grammatik

Die folgende formale Definition zeigt die Grammatik in BNF-Format, der einen Lambda-Ausdruck:

Lambda-Ausdruck

   : Lambda-Introducer Lambda-Parameterdeklarationopt - Anweisung

Lambda-introducer

   : [lambda-captureopt]

Lambda-capture

   : Capture-Standard

   | Capture-Liste

   | Capture-Standard-,Capture-Liste

Capture-Standard

   : &

   | =

Capture-Liste

   : erfassen

   | Capture-Liste,erfassen

Erfassen

   : Bezeichner

   | &Bezeichner

   | this

Lambda-Parameters-Deklaration

   : (Lambda-Deklaration Parameterlisteopt) änderbaren Spezifikationopt Ausnahmespezifikationopt Lambda-Rückgabe Typ-Klauselopt

Lambda-Deklaration Parameterliste

   : Lambda-Parameter

   | Lambda-Parameter,Lambda-Deklaration Parameterliste

Lambda-parameter

   : Decl-Spezifizierer-Seq-Declarator

Lambda-Rückgabe Typ-Klausel

   : ->type-id

Der folgende Abschnitt beschreibt, wie die Grammatik auf das Beispiel in der Einführung bezieht.

Eigenschaften von Lambda-Ausdrücken

In der folgenden Abbildung wird die Grammatik im Beispiel.

Die strukturellen Elemente eines Lambda-Ausdrucks

Die Positionsnummern in der Abbildung sind wie folgt:

  1. Lambda-Introducer (genannt capture-Klausel weiter unten in diesem Thema)

  2. Lambda-Deklaration Parameterliste (genannt Parameterliste weiter unten in diesem Thema)

  3. änderbare Spezifikation (genannt änderbaren Spezifikation weiter unten in diesem Thema)

  4. Ausnahmespezifikation (genannt Ausnahmespezifikation weiter unten in diesem Thema)

  5. Lambda-Rückgabe Typ-Klausel (genannt Rückgabetyp weiter unten in diesem Thema)

  6. zusammengesetzte Anweisung (genannt Lambda-Text weiter unten in diesem Thema)

In den folgenden Abschnitten beschreiben die Grammatik im Detail.

Dd293603.collapse_all(de-de,VS.110).gifKlausel erfassen

Ein Lambda-Ausdruck kann eine beliebige Variable zugreifen, die automatische Speicherung Dauer hat und im umschließenden Gültigkeitsbereich zugegriffen werden kann.Die Capture-Klausel gibt an, ob der Hauptteil der Lambda-Ausdruck Variablen im umschließenden Gültigkeitsbereich durch Wert oder Verweis zugreift: Variablen, die das kaufmännische und-Zeichen (&) Präfix erfolgt durch einen Verweis und Variablen, die nicht die & Präfix Wert abgerufen werden.Der leere Capture-Klausel, [], gibt an, dass der Hauptteil der Lambda-Ausdruck keine Variablen im umschließenden Gültigkeitsbereich zugreift.

Die Standard Capture-Modus gibt an, ob Capture Variablen, die Sie nicht explizit angeben durch Wert oder Verweis erfasst werden.Sie können angeben, dass den Standard-Capture-Modus (capture-default in der Syntax) durch die Angabe & oder = als das erste Element der Capture-Klausel.Die & Element angibt, ob der Hauptteil der Lambda-Ausdruck alle erfasste Variablen Verweis zugreift, wenn Sie ausdrücklich anders angegeben.Die = Element angibt, ob der Hauptteil der Lambda-Ausdruck alle erfasste Variablen Wert zugreift, wenn Sie ausdrücklich anders angegeben.Beispielsweise, wenn der Hauptteil eines Lambda-Ausdrucks externe Variable zugreift total durch einen Verweis und externe Variable factor Wert, dann die folgenden Capture-Klauseln sind gleichwertig:

[&total, factor]
[&, factor]
[=, &total]

Sie können die Lambda-Ausdrücke in den Körper der Methode einer Klasse.Übergeben Sie die this Zeiger auf der Capture-Klausel, um den Zugriff auf die Methoden und Datenmember der einschließenden Klasse zu ermöglichen.Ein Beispiel für die Verwendung von Lambda-Ausdruck mit Klassenmethoden, finden Sie unter Beispiel: verwenden einen Lambda-Ausdruck in einer Methode im Thema Beispiele für Lambda-Ausdrücke.

Dd293603.collapse_all(de-de,VS.110).gifParameterliste

Die Parameterliste für einen Lambda-Ausdruck ähnelt die Parameterliste für eine Funktion mit den folgenden Ausnahmen:

  • Die Parameterliste kann keine Standardargumente haben.

  • Die Parameterliste kann keine Argumentliste mit variabler Länge haben.

  • Die Parameterliste kann nicht Parameter Unbenannt haben.

Ein Lambda-Ausdruck kann ein anderes Lambdaausdruck als Argument in Anspruch nehmen.Weitere Informationen finden Sie unter Higher-Order Lambda-Ausdrücke im Thema Beispiele für Lambda-Ausdrücke.

Die Parameterliste für einen Lambda-Ausdruck ist optional.Sie können die Liste der Parameter auslassen, wenn Sie Argumente nicht an den Lambda-Ausdruck übergeben, und Sie nicht bieten die mutable-specification, exception-specification, und lambda-return-type-clause Elemente.Das folgende Beispiel zeigt einen Lambda-Ausdruck, der Liste die Parameter fehlt:

// lambda_parameter_list.cpp
int main()
{
   int x = 4;
   int y = 5;
   int z = [=] { return x + y; }();
}

Dd293603.collapse_all(de-de,VS.110).gifÄnderbare Spezifikation

Das änderbaren Spezifikation Teil ermöglicht die Stelle eines Lambda-Ausdrucks Variablen zu ändern, die vom Wert erfasst werden.Im vorhergehenden Beispiel wird die mutable Schlüsselwort so, dass der Textkörper des Lambda-Ausdrucks seine Kopien der externen Variablen ändern kann x und y, die der Lambda-Ausdruck als Wert erfasst.Da der Lambda-Ausdruck Variablen erfasst x und y Wert, ihre Werte bleiben 1 nach dem Aufruf von generate_n.

Dd293603.collapse_all(de-de,VS.110).gifAusnahmespezifikation

Sie können die throw() Ausnahmespezifikation an, dass ein Lambda-Ausdruck keine Ausnahmen auslöst.Wie mit regelmäßigen Funktionen der Visual C++-Compiler eine Warnung generiert C4297 erklärt ein Lambda-Ausdruck der throw() Ausnahmespezifikation und der Lambda-Nachrichtentext löst eine Ausnahme auf, wie im folgenden Beispiel gezeigt:

// throw_lambda_expression.cpp
int main() // C4297 expected
{
   []() throw() { throw 5; }();
}

Weitere Informationen zu Ausnahmespezifikationen finden Sie unter Ausnahmespezifikation.

Dd293603.collapse_all(de-de,VS.110).gifRückgabetyp

Der Rückgabetyp Teil einen Lambda-Ausdruck ähnelt den Rückgabetyp Teil eine normale Methode oder Funktion.Jedoch der Rückgabetyp folgt der Parameterliste und Sie müssen -> vor dem Rückgabetyp.

Sie können den Rückgabetyp Teil einen Lambda-Ausdruck auslassen, wenn der Lambda-Nachrichtentext eine einzige return-Anweisung enthält oder der Lambda-Ausdruck keinen Wert zurück.Wenn der Lambda-Nachrichtentext aus einem einzigen return-Anweisung besteht, deduces der Compiler den Rückgabetyp vom Typ des Ausdrucks zurück.Andernfalls deduces der Compiler den Rückgabetyp sein void.

Ein Lambda-Ausdruck kann ein anderes Lambda-Ausdruck als ihren Rückgabewert erzeugen.Weitere Informationen finden Sie unter Higher-Order Lambda-Ausdrücke im Thema Beispiele für Lambda-Ausdrücke.

Dd293603.collapse_all(de-de,VS.110).gifLambda-Text

Der Lambda-Körperteil einen Lambda-Ausdruck kann alles enthalten, das der Körper einer normalen Methode oder Funktion enthalten kann.Der Hauptteil einer normalen Funktion und einen Lambda-Ausdruck kann die folgenden Typen von Variablen zugreifen:

  • Parameter

  • Lokal deklarierte Variablen

  • Datenmember der Klasse (wenn innerhalb einer Klasse deklariert wird)

  • Jede Variable, die statischen Speicher Dauer (z. B. globale Variablen)

Darüber hinaus kann ein Lambda-Ausdruck Variablen zugreifen, die sie aus den einschließenden Gültigkeitsbereich erfasst.Eine Variable ist explizit erfasst erscheint in der Capture-Klausel der Lambda-Ausdruck.Andernfalls die Variable ist implizit erfasst.Der Hauptteil der Lambda-Ausdruck verwendet den Standard-Capture-Modus zu Zugriff-Variablen, die implizit erfasst werden.

Die lambda_parameter_list.cpp Beispiel implizit erfasst die lokalen Variablen x und y Wert.Das folgende Beispiel enthält einen Lambda-Ausdruck, der die Variable explizit erfasst n durch einen Wert und implizit erfasst die Variable m als Verweis:

// captures_lambda_expression.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

int main()
{
   int m = 0, n = 0;
   [&, n] (int a) mutable { m = ++n + a; }(4);
   cout << m << endl << n << endl;
}

In diesem Beispiel gibt Folgendes an der Konsole:

5
0

Da die Variable n vom Wert, der Wert bleibt erfasst 0 nach dem Aufruf der Lambda-Ausdruck.

Obwohl ein Lambda-Ausdruck nur Variablen, die automatische Speicherung Dauer haben erfassen kann, können Sie Variablen verwenden, die statischen Speicher Dauer im Textkörper des Lambda-Ausdruck.Im folgenden Beispiel wird die generate -Funktion und ein Lambda-Ausdruck zuweisen ein Werts für jedes Element in ein vector Objekt.Der Lambda-Ausdruck ändert die statische Variable den Wert des nächsten Elements generieren.

// lambda_static_variable.cpp
// compile with: /c /EHsc
#include <vector>
#include <algorithm>
using namespace std;

void fillVector(vector<int>& v)
{
   // A local static variable.
   static int nextValue = 1;

   // The lambda expression that appears in the following call to
   // the generate function modifies and uses the local static 
   // variable nextValue.
   generate(v.begin(), v.end(), [] { return nextValue++; });
}

Weitere Informationen zu den generate funktionieren, finden Sie unter Generieren.

Siehe auch

Referenz

Lambda-Ausdrücke in C++

Beispiele für Lambda-Ausdrücke

Generieren

generate_n

for_each

Ausnahmespezifikation

Compilerwarnung (Stufe 1) C4297