Exemples d’expressions lambda
Cet article explique comment utiliser des expressions lambda dans vos programmes. Pour obtenir une vue d’ensemble des expressions lambda, veuillez consulter la rubrique Expressions lambda. Si vous souhaitez en savoir plus sur la structure d’une expression lambda, veuillez consulter la rubrique Syntaxe d’expression lambda.
Déclaration d’expressions lambda
Exemple 1
Une expression lambda étant typée, vous pouvez l’affecter à une variable auto
ou à un objet function
, comme indiqué dans l’exemple suivant :
// declaring_lambda_expressions1.cpp
// compile with: /EHsc /W4
#include <functional>
#include <iostream>
int main()
{
using namespace std;
// Assign the lambda expression that adds two numbers to an auto variable.
auto f1 = [](int x, int y) { return x + y; };
cout << f1(2, 3) << endl;
// Assign the same lambda expression to a function object.
function<int(int, int)> f2 = [](int x, int y) { return x + y; };
cout << f2(3, 4) << endl;
}
L'exemple génère cette sortie :
5
7
Notes
Si vous souhaitez en savoir plus, veuillez consulter les rubriques auto
, function
Classe et Appels de fonction.
Bien que les expressions lambda soient le plus souvent déclarées dans le corps d’une fonction, vous pouvez les déclarer partout où vous pouvez initialiser une variable.
Exemple 2
Le compilateur Microsoft C++ lie une expression lambda à ses variables capturées lorsque l’expression est déclarée plutôt que lorsque l’expression est appelée. L’exemple suivant montre une expression lambda qui capture la variable locale i
par valeur et la variable locale j
par référence. Puisque l’expression lambda capture i
par valeur, la réaffectation de i
ultérieurement dans le programme n’affecte pas le résultat de l’expression. Toutefois, puisque l’expression lambda enregistre j
par référence, la réaffectation de j
influence le résultat de l’expression.
// declaring_lambda_expressions2.cpp
// compile with: /EHsc /W4
#include <functional>
#include <iostream>
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;
}
L'exemple génère cette sortie :
47
Appel d’expressions lambda
Vous pouvez appeler une expression lambda immédiatement, comme indiqué dans l’extrait de code suivant. Le deuxième extrait montre comment transmettre une expression lambda en tant qu’argument de bibliothèque standard C++ tels que find_if
.
Exemple 1
Cet exemple déclare une expression lambda qui retourne la somme de deux entiers et appelle l’expression immédiatement avec les arguments 5
et 4
:
// 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;
}
L'exemple génère cette sortie :
9
Exemple 2
Cet exemple passe une expression lambda comme argument de la fonction find_if
. L’expression lambda retourne true
si son paramètre est un nombre pair.
// calling_lambda_expressions2.cpp
// compile with: /EHsc /W4
#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;
}
}
L'exemple génère cette sortie :
The first even number in the list is 42.
Notes
Si vous souhaitez en savoir plus sur la fonction find_if
, veuillez consulter la rubrique find_if
. Si vous souhaitez en savoir plus sur les fonctions de bibliothèque standard C++ qui effectuent des algorithmes communs, veuillez consulter la rubrique <algorithm>
.
Imbrication d’expressions lambda
Exemple
Vous pouvez imbriquer une expression lambda dans une autre, comme le montre l'exemple suivant. L’expression lambda interne multiplie son argument par 2 et retourne le résultat. L’expression lambda externe appelle l’expression lambda interne avec son argument et ajoute 3 au résultat.
// nesting_lambda_expressions.cpp
// compile with: /EHsc /W4
#include <iostream>
int main()
{
using namespace std;
// The following lambda expression contains a nested lambda
// expression.
int timestwoplusthree = [](int x) { return [](int y) { return y * 2; }(x) + 3; }(5);
// Print the result.
cout << timestwoplusthree << endl;
}
L'exemple génère cette sortie :
13
Notes
Dans cet exemple, [](int y) { return y * 2; }
est l’expression lambda imbriquée.
Fonctions lambda d’ordre supérieur
Exemple
De nombreux langages de programmation prennent en charge le concept de fonction d’ordre supérieur. Une fonction d'ordre supérieur est une expression lambda qui prend une autre expression lambda comme argument ou qui retourne une expression lambda. Vous pouvez utiliser la classe de fonction function
pour permettre à une expression lambda C++ de se comporter comme une fonction d’ordre supérieur. L'exemple suivant présente une expression lambda qui retourne un objet function
et une expression lambda qui prend un objet function
comme argument.
// higher_order_lambda_expression.cpp
// compile with: /EHsc /W4
#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 addtwointegers = [](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 multiplies by 2.
auto higherorder = [](const function<int(int)>& f, int z) {
return f(z) * 2;
};
// Call the lambda expression that is bound to higherorder.
auto answer = higherorder(addtwointegers(7), 8);
// Print the result, which is (7+8)*2.
cout << answer << endl;
}
L'exemple génère cette sortie :
30
Utilisation d’une expression lambda dans une fonction
Exemple
Vous pouvez utiliser les expressions lambda dans le corps d'une fonction. L’expression lambda peut accéder à toute donnée membre ou fonction accessible à la fonction englobante. Vous pouvez explicitement ou implicitement capturer le pointeur this
pour fournir l'accès aux fonctions et données membres de la classe englobante.
Visual Studio 2017 version 15.3 et ultérieure (disponible avec /std:c++17
et versions ultérieures) : capture de this
par la valeur ([*this]
) lorsque l’expression lambda sera utilisée dans des opérations asynchrones ou parallèles où le code peut s’exécuter une fois que l’objet d’origine devient hors de portée.
Vous pouvez utiliser le pointeur this
explicitement dans une fonction, comme indiqué ci-dessous :
// capture "this" by reference
void ApplyScale(const vector<int>& v) const
{
for_each(v.begin(), v.end(),
[this](int n) { cout << n * _scale << endl; });
}
// capture "this" by value (Visual Studio 2017 version 15.3 and later)
void ApplyScale2(const vector<int>& v) const
{
for_each(v.begin(), v.end(),
[*this](int n) { cout << n * _scale << endl; });
}
Vous pouvez également capturer le pointeur this
implicitement :
void ApplyScale(const vector<int>& v) const
{
for_each(v.begin(), v.end(),
[=](int n) { cout << n * _scale << endl; });
}
L'exemple suivant montre la classe Scale
, qui encapsule une valeur d'échelle.
// function_lambda_expression.cpp
// compile with: /EHsc /W4
#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(), [=](int n) { cout << n * _scale << endl; });
}
private:
int _scale;
};
int main()
{
vector<int> values;
values.push_back(1);
values.push_back(2);
values.push_back(3);
values.push_back(4);
// Create a Scale object that scales elements by 3 and apply
// it to the vector object. doesn't modify the vector.
Scale s(3);
s.ApplyScale(values);
}
L'exemple génère cette sortie :
3
6
9
12
Notes
La fonction ApplyScale
utilise une expression lambda pour imprimer le produit de la valeur d’échelle et de chaque élément d’un objet vector
. L’expression lambda capture implicitement le pointeur this
afin qu’elle puisse accéder au membre _scale
.
Utilisation d’expressions lambda avec des modèles
Exemple
Les expressions lambda étant typées, vous pouvez les utiliser avec des modèles C++. L'exemple suivant illustre les fonctions negate_all
et print_all
. La fonction negate_all
applique l’opérateur operator-
unaire à chaque élément de l’objet vector
. La fonction print_all
affiche chaque élément de l'objet vector
sur la console.
// template_lambda_expression.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
// Negates each element in the vector object. Assumes signed data type.
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 signed integers with a few elements.
vector<int> v;
v.push_back(34);
v.push_back(-43);
v.push_back(56);
print_all(v);
negate_all(v);
cout << "After negate_all():" << endl;
print_all(v);
}
L'exemple génère cette sortie :
34
-43
56
After negate_all():
-34
43
-56
Notes
Si vous souhaitez en savoir plus sur les modèles C++, veuillez consulter la rubrique Modèles.
Gestion des exceptions
Exemple
Le corps d'une expression lambda suit les règles de la gestion structurée des exceptions (SEH) et la gestion des exceptions C++. Vous pouvez gérer une exception levée dans le corps d'une expression lambda ou différer la gestion des exceptions dans la portée englobante. L’exemple suivant utilise la fonction for_each
et une expression lambda pour remplir un objet vector
avec les valeurs d’un autre. Il utilise un bloc try
/catch
pour gérer l'accès non valide au premier vecteur.
// eh_lambda_expression.cpp
// compile with: /EHsc /W4
#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 valid subscript. It will trigger an 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;
};
}
L'exemple génère cette sortie :
Caught 'invalid vector<T> subscript'.
Notes
Si vous souhaitez en savoir plus, veuillez consulter la rubrique Gestion des exceptions.
Utilisation d’expressions lambda avec des types managés (C++/CLI)
Exemple
La clause de capture d’une expression lambda ne peut pas contenir de variable de type managé. Toutefois, vous pouvez passer un argument qui a un type managé dans la liste de paramètres d'une expression lambda. L'exemple suivant contient une expression lambda qui capture la variable non managée locale ch
par valeur et prend un objet System.String comme paramètre.
// 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");
}
L'exemple génère cette sortie :
Hello!
Notes
Vous pouvez également utiliser vos expressions lambda avec la bibliothèque STL/CLR. Si vous souhaitez en savoir plus, veuillez consulter la rubrique Référence de bibliothèque STL/CLR.
Important
Les expressions lambda ne sont pas prises en charge dans les entités managées suivantes du CLR (common language runtime) : ref class
, ref struct
, value class
et value struct
.
Voir aussi
Expressions lambda
Syntaxe d’expression lambda
auto
function
Classe
find_if
<algorithm>
Appel de fonction
Modèles
Gestion des exceptions
Référence de bibliothèque STL/CLR
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour