Esempi di espressioni lambda

Questo argomento contiene esempi di come utilizzare le espressioni lambda nei programmi.Per una panoramica delle espressioni lambda, vedere Espressioni lambda in C++.Per ulteriori informazioni sulla struttura di un'espressione lambda, vedere Sintassi delle espressioni lambda.

Argomenti della sezione

Esempio: Dichiarazione di espressioni lambda

Esempio: Espressioni lambda chiamante

Esempio: Espressioni lambda di annidamento

Esempio: Funzioni lambda più di ordine superiore

Esempio: Utilizzando un'espressione lambda in un metodo

Esempio: Utilizzo di espressioni lambda con i modelli

Esempio: Gestione delle eccezioni

Esempio: Utilizzo di espressioni lambda con i tipi gestiti

Esempio: Dichiarazione di espressioni lambda

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Poiché un'espressione lambda è tipizzata, è possibile assegnarlo a una variabile auto o a un oggetto function, come illustrato nel seguente esempio:

Dd293599.collapse_all(it-it,VS.110).gifCodice

// declaring_lambda_expressions1.cpp
#include <functional>

int main()
{
   // Assign the lambda expression that adds two numbers to an auto variable.
   auto f1 = [] (int x, int y) { return x + y; }; 

   // Assign the same lambda expression to a function object.
   function<int (int, int)> f2 = [] (int x, int y) { return x + y; };
}

Dd293599.collapse_all(it-it,VS.110).gifCommenti

Per ulteriori informazioni sulla parola chiave auto, vedere parola chiave auto (deduzione del tipo).Per ulteriori informazioni su function class, vedere function Class.

Sebbene le espressioni lambda più frequentemente vengano dichiarate nel corpo di un metodo o una funzione, è possibile dichiararli in un punto che è possibile inizializzare una variabile.

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Le associazioni del compilatore di Visual C++ un'espressione lambda alle variabili acquisite quando l'espressione viene dichiarata anziché quando l'espressione viene chiamata.Nell'esempio seguente viene illustrata un'espressione lambda che acquisisce la variabile locale i per valore e la variabile locale j per riferimento.Poiché l'espressione lambda acquisisce i per valore, la riassegnazione i più avanti nel programma non influisce sul risultato dell'espressione.Tuttavia, poiché l'espressione lambda acquisisce j per riferimento, la riassegnazione j sul risultato dell'espressione.

Dd293599.collapse_all(it-it,VS.110).gifCodice

// declaring_lambda_expressions2.cpp
// compile with: /EHsc
#include <iostream>
#include <functional>

int main()
{
   using namespace std;

   int i = 3;
   int j = 5;

   // The following lambda expression captures i by value and
   // j by reference.
   function<int (void)> f = [i, &j] { return i + j; };

   // Change the values of i and j.
   i = 22;
   j = 44;

   // Call f and print its result.
   cout << f() << endl;
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

47

Dd293599.collapse_all(it-it,VS.110).gifCommenti

[Argomenti della sezione]

Esempio: Espressioni lambda chiamante

È possibile chiamare direttamente un'espressione lambda o passarlo come argomento agli algoritmi standard (STL) della libreria di modelli come find_if.

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio seguente viene dichiarata un'espressione lambda che restituisce la somma di due numeri interi e richiama l'espressione immediatamente agli argomenti 5 e 4:

Dd293599.collapse_all(it-it,VS.110).gifCodice

// calling_lambda_expressions1.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;
   int n = [] (int x, int y) { return x + y; }(5, 4);
   cout << n << endl;
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

9

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio passa un'espressione lambda come argomento alla funzione find_if.L'espressione lambda restituisce true se il parametro è un numero pari.

Dd293599.collapse_all(it-it,VS.110).gifCodice

// calling_lambda_expressions2.cpp
// compile with: /EHsc
#include <list>
#include <algorithm>
#include <iostream>

int main()
{
   using namespace std;

   // Create a list of integers with a few initial elements.
   list<int> numbers;
   numbers.push_back(13);
   numbers.push_back(17);
   numbers.push_back(42);
   numbers.push_back(46);
   numbers.push_back(99);

   // Use the find_if function and a lambda expression to find the 
   // first even number in the list.
   const list<int>::const_iterator result =
      find_if(numbers.begin(), numbers.end(),
         [](int n) { return (n % 2) == 0; });

   // Print the result.
   if (result != numbers.end())
   {
       cout << "The first even number in the list is " 
            << (*result) 
            << "." 
            << endl;
   }
   else
   {
       cout << "The list contains no even numbers." 
            << endl;
   }
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

The first even number in the list is 42.

Dd293599.collapse_all(it-it,VS.110).gifCommenti

Per ulteriori informazioni sulla funzione find_if, vedere find_if.Per ulteriori informazioni sulle funzioni della libreria STL che eseguono algoritmi, vedere <algorithm>.

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

È possibile richiamare un'espressione lambda assegnata a una variabile utilizzando l'operatore di chiamata di funzione, operator().Nell'esempio assegna un'espressione lambda a una variabile auto quindi utilizza l'operatore di chiamata di funzione per richiamare l'espressione lambda:

Dd293599.collapse_all(it-it,VS.110).gifCodice

// calling_lambda_expressions3.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;

   // Assign the lambda expression that adds two numbers to an 
   // auto variable.
   auto f = [] (int x, int y) { return x + y; };

   // Invoke the function object and print its result.
   cout << f(21, 12) << endl;
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

33

Dd293599.collapse_all(it-it,VS.110).gifCommenti

Per ulteriori informazioni sull'operatore di chiamata di funzione, vedere Chiamata di funzione (C++).

[Argomenti della sezione]

Esempio: Espressioni lambda di annidamento

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

È possibile annidare un'espressione lambda in un altro.Nell'esempio seguente viene illustrata un'espressione lambda che contiene un'altra espressione lambda.L'espressione lambda interna moltiplica il relativo argomento per 2 e restituisce il risultato.L'espressione lambda esterna chiama l'espressione lambda interna con l'argomento e aggiunge 3 al risultato.

Dd293599.collapse_all(it-it,VS.110).gifCodice

// nesting_lambda_expressions.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;

   // The following lambda expression contains a nested lambda
   // expression.
   int m = [](int x) 
      { return [](int y) { return y * 2; }(x) + 3; }(5);

   // Print the result.
   cout << m << endl;
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

13

Dd293599.collapse_all(it-it,VS.110).gifCommenti

In questo esempio, [](int y) { return y * 2; } è l'espressione lambda annidata.

[Argomenti della sezione]

Esempio: Funzioni lambda più di ordine superiore

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Molti linguaggi di programmazione supportano il concetto di una funzione di ordine superiore. Una funzione di ordine superiore è un'espressione lambda che accetta un'altra espressione lambda come argomento o che restituisce un'espressione lambda.È possibile utilizzare la classe function per consentire l'espressione lambda C++ viene comportiate come una funzione di ordine superiore.Nell'esempio seguente viene illustrata un'espressione lambda che restituisce un oggetto function e un'espressione lambda che accetta un oggetto function come argomento:

Dd293599.collapse_all(it-it,VS.110).gifCodice

// higher_order_lambda_expression.cpp
// compile with: /EHsc
#include <iostream>
#include <functional>

int main()
{
   using namespace std;

   // The following code declares a lambda expression that returns 
   // another lambda expression that adds two numbers. 
   // The returned lambda expression captures parameter x by value.
   auto g = [](int x) -> function<int (int)> 
      { return [=](int y) { return x + y; }; };

   // The following code declares a lambda expression that takes another
   // lambda expression as its argument.
   // The lambda expression applies the argument z to the function f
   // and adds 1.
   auto h = [](const function<int (int)>& f, int z) 
      { return f(z) + 1; };

   // Call the lambda expression that is bound to h. 
   auto a = h(g(7), 8);

   // Print the result.
   cout << a << endl;
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

16

Dd293599.collapse_all(it-it,VS.110).gifCommenti

[Argomenti della sezione]

Esempio: Utilizzando un'espressione lambda in un metodo

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

È possibile utilizzare le espressioni lambda nel corpo di un metodo.L'espressione lambda può accedere a qualsiasi metodo o membro dati che il metodo contenitore può accedere.È possibile in modo esplicito o implicito acquisire il puntatore this per fornire l'accesso ai metodi e membri dati della classe interna.

Nell'esempio seguente viene illustrata la classe Scale, che incapsula un valore di ridimensionamento.Il metodo ApplyScale utilizza un'espressione lambda per stampare il risultato di ogni elemento in un oggetto vector e il valore di ridimensionamento.L'espressione lambda in modo esplicito acquisisce il puntatore this in modo che possa accedere al membro _scale.

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

class Scale
{
public:
   // The constructor.
   explicit Scale(int scale)
      : _scale(scale)
   {
   }

   // Prints the product of each element in a vector object 
   // and the scale value to the console.
   void ApplyScale(const vector<int>& v) const
   {
      for_each(v.begin(), v.end(), 
         [this](int n) { cout << n * _scale << endl; });
   }

private:
   int _scale;
};

int main()
{
   vector<int> values;
   values.push_back(3);
   values.push_back(6);
   values.push_back(9);

   // Create a Scale object that scales elements by 3 and apply
   // it to the vector object.
   Scale s(3);
   s.ApplyScale(values);
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

9
18
27

Dd293599.collapse_all(it-it,VS.110).gifCommenti

È possibile utilizzare il puntatore this in modo esplicito in un metodo, come illustrato nell'esempio seguente:

void ApplyScale(const vector<int>& v) const
{
   for_each(v.begin(), v.end(), 
      [this](int n) { cout << n * this->_scale << endl; });
}

È inoltre possibile acquisire il puntatore this in modo implicito, come illustrato nel seguente esempio:

void ApplyScale(const vector<int>& v) const
{
   for_each(v.begin(), v.end(), 
      [=](int n) { cout << n * _scale << endl; });
}

[Argomenti della sezione]

Esempio: Utilizzo di espressioni lambda con i modelli

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Poiché le espressioni lambda sono tipizzate, è possibile utilizzarle con i modelli di C++.Nell'esempio seguente vengono illustrate le funzioni negate_all e print_all.La funzione negate_all si applica operator- unario a ogni elemento dell'oggetto vector.La funzione print_all visualizza ogni elemento nell'oggetto vector nella console.

Dd293599.collapse_all(it-it,VS.110).gifCodice

// template_lambda_expression.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// Negates each element in the vector object.
template <typename T> 
void negate_all(vector<T>& v)
{
    for_each(v.begin(), v.end(), [] (T& n) { n = -n; } );
}

// Prints to the console each element in the vector object.
template <typename T> 
void print_all(const vector<T>& v)
{
   for_each(v.begin(), v.end(), [] (const T& n) { cout << n << endl; } );
}

int main()
{
   // Create a vector of integers with a few initial elements.
   vector<int> v;
   v.push_back(34);
   v.push_back(-43);
   v.push_back(56);

   // Negate each element in the vector.
   negate_all(v);

   // Print each element in the vector.
   print_all(v);
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

-34
43
-56

Dd293599.collapse_all(it-it,VS.110).gifCommenti

Per ulteriori informazioni sui modelli C++, vedere Modelli.

[Argomenti della sezione]

Esempio: Gestione delle eccezioni

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

Il corpo di un'espressione lambda segue le regole per la gestione delle eccezioni strutturata (SEH) di gestione delle eccezioni C++.È possibile gestire un'eccezione generata un'eccezione nel corpo di un'espressione lambda o rinviare la gestione delle eccezioniambito che lo contiene.Nell'esempio seguente viene utilizzata la funzione for_each e un'espressione lambda per riempire un oggetto vector valori di un altro.Viene utilizzato un bloccocatch / tryper gestire l'accesso non valido al primo vettore.

Dd293599.collapse_all(it-it,VS.110).gifCodice

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

int main()
{
   // Create a vector that contains 3 elements.
   vector<int> elements(3);

   // Create another vector that contains index values.
   vector<int> indices(3);
   indices[0] = 0;
   indices[1] = -1; // This is not a subscript. It will trigger the exception.
   indices[2] = 2;

   // Use the values from the vector of index values to 
   // fill the elements vector. This example uses a 
   // try/catch block to handle invalid access to the 
   // elements vector.
   try
   {
       for_each(indices.begin(), indices.end(), 
           [&] (int index) { elements.at(index) = index; });
   }
   catch (const out_of_range& e) 
   {
       cerr << "Caught '" << e.what() << "'." << endl;
   };
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

Caught 'invalid vector<T> subscript'.

Dd293599.collapse_all(it-it,VS.110).gifCommenti

Per ulteriori informazioni sulla gestione delle eccezioni, vedere Gestione delle eccezioni in Visual C++.

[Argomenti della sezione]

Esempio: Utilizzo di espressioni lambda con i tipi gestiti

Dd293599.collapse_all(it-it,VS.110).gifDescrizione

La clausola di acquisizione di un'espressione lambda non può contenere una variabile con un tipo gestito.Tuttavia, è possibile passare un argomento con un tipo gestito all'elenco di parametri di un'espressione lambda.L'esempio seguente contiene un'espressione lambda che acquisisce ch variabile locale non gestito per valore e accetta un oggetto System.String come parametro:

Dd293599.collapse_all(it-it,VS.110).gifCodice

// managed_lambda_expression.cpp
// compile with: /clr
using namespace System;

int main()
{
    char ch = '!'; // a local unmanaged variable
    
    // The following lambda expression captures local variables
    // by value and takes a managed String object as its parameter.
    [=] (String ^s) 
        { Console::WriteLine(s + Convert::ToChar(ch)); }("Hello");
}

Dd293599.collapse_all(it-it,VS.110).gifOutput

Hello!

Dd293599.collapse_all(it-it,VS.110).gifCommenti

È possibile utilizzare anche le espressioni lambda con la libreria STL/CLR.Per ulteriori informazioni su STL/CLR, vedere Riferimenti alla libreria STL/CLR.

[Argomenti della sezione]

Vedere anche

Riferimenti

Espressioni lambda in C++

Sintassi delle espressioni lambda

parola chiave auto (deduzione del tipo)

function Class

find_if

<algorithm>

Chiamata di funzione (C++)

Gestione delle eccezioni in Visual C++

Altre risorse

Modelli

Riferimenti alla libreria STL/CLR