Sintassi delle espressioni lambda

In questo argomento viene descritta la sintassi delle espressioni lambda.Viene fornito un esempio che illustra gli elementi strutturali di un'espressione lambda e come questi elementi si riferiscono all'esempio.

Il seguente programma utilizza le espressioni lambda con due algoritmi STL: generate_n e for_each.L'espressione lambda che viene visualizzato nella chiamata alla generate_n funzione assegna un elemento di un vector oggetto per la somma dei due elementi precedenti.L'espressione lambda che viene visualizzato nella chiamata alla for_each funzione consente di stampare un elemento dello stesso vector oggetto nella console.

// 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;
}

Per ulteriori informazioni sui generate_n funzione, vedere generate_n.Per ulteriori informazioni sui for_each funzione, vedere for_each.

Le sezioni seguenti descrivono la grammatica di un'espressione lambda e il modo in cui ogni elemento si riferisce all'esempio precedente.

Grammatica di espressione lambda

La seguente definizione formale viene illustrata la grammatica in formato BNF, di un'espressione lambda:

espressione lambda

   : lambda introduzione dichiarazione parametro lambdaopz composto-istruzione

lambda-introduzione

   : [lambda-captureopt]

acquisizione lambda

   : acquisizione predefinita

   | elenco di acquisizione

   | acquisizione predefinita,elenco di acquisizione

acquisizione predefinita

   : &

   | =

elenco di acquisizione

   : di acquisizione

   | elenco di acquisizione,di acquisizione

acquisizione

   : identificatore

   | &identificatore

   | this

dichiarazione di parametro lambda

   : (elenco dichiarazione di parametro lambdaopz) modificabile specificaopz specifica eccezioneopz lambda-return-type-clauseopz

elenco dichiarazione di parametro lambda

   : parametro lambda

   | il parametro lambda,elenco dichiarazione di parametro lambda

parametro lambda

   : declarator decl-identificatore-seq

lambda-return-type-clause

   : ->type-id

Nella sezione seguente descrive la relazione con l'esempio dell'introduzione della grammatica.

Proprietà delle espressioni Lambda

Nell'illustrazione che segue associa la grammatica per l'esempio.

Elementi strutturali di un'espressione lambda

Le didascalie nell'illustrazione sono i seguenti:

  1. Introduzione lambda (in appresso acquisire clausola più avanti in questo argomento)

  2. elenco dichiarazione di parametro lambda (in appresso elenco dei parametri di più avanti in questo argomento)

  3. modificabile specifica (in appresso modificabile specifica più avanti in questo argomento)

  4. Specifica di eccezione (in appresso specifica eccezione più avanti in questo argomento)

  5. lambda-return-type-clause (in appresso tipo di valore restituito più avanti in questo argomento)

  6. istruzione composti (in appresso corpo lambda più avanti in questo argomento)

Le sezioni seguenti descrivono la grammatica in modo più dettagliato.

Dd293603.collapse_all(it-it,VS.110).gifClausola di acquisizione

Un'espressione lambda può accedere a qualsiasi variabile che ha la durata di archiviazione automatica e che è possibile accedere nell'ambito di inclusione.La clausola di acquisizione consente di specificare se il corpo dell'espressione lambda che accede a variabili nell'ambito di inclusione per valore o per riferimento: le variabili con la e commerciale (&) prefisso avviene mediante riferimento e le variabili che non dispongono di & prefisso a cui si accede dal valore.La clausola di cattura vuota, [], indica che il corpo dell'espressione lambda non accede variabili nell'ambito di inclusione.

Il modalità di acquisizione predefinita specifica se le variabili di acquisizione non si specifica in modo esplicito vengono acquisite per valore o per riferimento.È possibile specificare la modalità di acquisizione predefinita (capture-default nella sintassi) specificando & o = come primo elemento della clausola di acquisizione.Il & elemento specifica che il corpo dell'espressione lambda accede acquisite in tutte le variabili per riferimento a meno che non si specifichi diversamente.Il = elemento specifica che il corpo dell'espressione lambda accede acquisite in tutte le variabili dal valore a meno che non si specifichi diversamente.Ad esempio, se il corpo di un'espressione lambda accede alla variabile esterna total da riferimento e la variabile esterna factor dal valore, quindi le seguenti clausole di acquisizione sono equivalenti:

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

È possibile utilizzare le espressioni lambda nel corpo di un metodo della classe.Passare il this puntatore alla clausola di acquisizione per fornire l'accesso ai membri dati e metodi della classe che contiene.Per un esempio di come utilizzare l'espressione lambda con i metodi della classe, vedere esempio: utilizzo di un'espressione Lambda in un metodo nell'argomento Esempi di espressioni lambda.

Dd293603.collapse_all(it-it,VS.110).gifElenco di parametri

L'elenco dei parametri per un'espressione lambda è simile all'elenco di parametri per una funzione, con le seguenti eccezioni:

  • L'elenco di parametri non può avere argomenti predefiniti.

  • L'elenco di parametri non può avere un elenco di argomenti di lunghezza variabile.

  • L'elenco di parametri non può contenere parametri senza nome.

Un'espressione lambda può richiedere un'altra espressione lambda come argomento.Per ulteriori informazioni, vedere espressioni Lambda di ordine superiore nell'argomento Esempi di espressioni lambda.

L'elenco dei parametri per un'espressione lambda è facoltativo.È possibile omettere l'elenco di parametri, se non si passano gli argomenti per l'espressione lambda e non forniscono il mutable-specification, exception-specification, e lambda-return-type-clause gli elementi.Nell'esempio riportato di seguito viene illustrata un'espressione lambda che consente di omettere l'elenco di parametri:

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

Dd293603.collapse_all(it-it,VS.110).gifSpecifica modificabile

La parte specifica modificabile consente il corpo di un'espressione lambda per modificare le variabili che vengono acquisite dal valore.Nell'esempio precedente viene utilizzato il mutable parola chiave in modo che il corpo dell'espressione lambda può modificare le copie delle variabili esterne x e y, che l'espressione lambda acquisisce dal valore.Poiché l'espressione lambda acquisisce le variabili x e y valore, di mantenere i valori 1 dopo la chiamata a generate_n.

Dd293603.collapse_all(it-it,VS.110).gifSpecifica di eccezione

È possibile utilizzare la throw() specifica di eccezione per indicare che l'espressione lambda non genera alcuna eccezione.Come con le funzioni normali, il compilatore Visual C++ genera l'avviso C4297 se un'espressione lambda dichiara il throw() specifica di eccezione e il corpo della lambda genera un'eccezione, come illustrato nell'esempio riportato di seguito:

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

Per ulteriori informazioni sulle eccezioni specifiche, vedere Specifiche di eccezione.

Dd293603.collapse_all(it-it,VS.110).gifTipo restituito

La parte del tipo restituito di un'espressione lambda è simile a parte il tipo restituito di un metodo ordinario o una funzione.Tuttavia, il tipo restituito segue l'elenco di parametri e deve includere -> prima del tipo restituito.

Se il corpo della lambda contiene una singola istruzione return o l'espressione lambda non restituisce un valore, è possibile omettere la parte del tipo restituito di un'espressione lambda.Se il corpo della lambda è costituito da una singola istruzione return, il compilatore deduces il tipo restituito dal tipo di espressione restituita.In caso contrario il compilatore deduces il tipo restituito da void.

Un'espressione lambda può produrre un'altra espressione lambda come valore restituito.Per ulteriori informazioni, vedere espressioni Lambda di ordine superiore nell'argomento Esempi di espressioni lambda.

Dd293603.collapse_all(it-it,VS.110).gifCorpo della lambda

La parte del corpo lambda di un'espressione lambda può contenere qualsiasi elemento che può contenere il corpo di un metodo ordinario o una funzione.Il corpo di una funzione comune e un'espressione lambda può accedere i seguenti tipi di variabili:

  • Parametri

  • Variabili dichiarate localmente

  • Membri dati di classe (quando è dichiarata all'interno di una classe)

  • Qualsiasi variabile con durata di archiviazione statica (ad esempio, le variabili globali)

Inoltre, un'espressione lambda può accedere le variabili che consente l'acquisizione dall'ambito di inclusione.Una variabile è in modo esplicito acquisiti se viene visualizzata nella clausola acquisizione dell'espressione lambda.In caso contrario, la variabile è in modo implicito acquisito.Il corpo dell'espressione lambda utilizza la modalità di acquisizione predefinita per le variabili di accesso vengono acquisiti in modo implicito.

Il lambda_parameter_list.cpp esempio acquisisce in modo implicito le variabili locali x e y per valore.L'esempio seguente contiene un'espressione lambda che acquisisce in modo esplicito la variabile n per valore e in modo implicito acquisisce la variabile m con riferimento:

// 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 questo esempio consente di stampare quanto segue alla console:

5
0

Poiché la variabile n acquisiti dal valore, rimane i valore 0 dopo la chiamata per l'espressione lambda.

Anche se un'espressione lambda è in grado di acquisire solo le variabili con durata di archiviazione automatica, è possibile utilizzare variabili con durata di archiviazione statica nel corpo di un'espressione lambda.Nell'esempio riportato di seguito viene utilizzata la generate funzione e un'espressione lambda per assegnare un valore a ogni elemento in un vector oggetto.L'espressione lambda consente di modificare la variabile statica per generare il valore dell'elemento successivo.

// 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++; });
}

Per ulteriori informazioni sui generate funzione, vedere generate.

Vedere anche

Riferimenti

Espressioni lambda in C++

Esempi di espressioni lambda

generate

generate_n

for_each

Specifiche di eccezione

Avviso del compilatore (livello 1) C4297