Ce tutoriel n'est pas destiné au débutants, mais plutôt a ceux qui ont déjà un peu d’expérience en C++.
Les lambda ont été introduite dans le plus récent standard, le C++11, vérifiez bien que votre compilateur le supporte !
Headers nécessaires : <iostream> <vector> <algorithm>
Définition
Une lambda, c'est un objet que l'on peut appeler (et non, pas au tel ), parce quelles sont simples a déclarer, elles sont très souvent utiliser pour crée des petites fonctions a l’intérieur d'une fonction. On peut aussi les utiliser comme argument pour un algorithme. (exemples plus bas)
Création d'une lambda
Le prototype de base pour une lambda est le suivant :
PHP:
auto name = [capture list] (parameter list) -> return type {body};
- Auto : J'utilise auto pour que le compilateur puisse déduire le type.
- Name : Le nom de la lambda.
- Capture list : Cette liste contient les variables locales de la fonction que la lambda va utiliser. /!\ Par valeur et non référence !
- Parameter list : La liste des paramètres qu'on doit passer a la lambda ... exactement comme une fonction normale.
- Return type : Type que la lambda retourne.
- Body : Vraiment besoin d'expliquer ?
Voici un exemple d'une lambda qui retourne le nombre d'argument passes a la fonction Main ( int main(int nArgs,char* pArgs[] ) :
PHP:
auto getArgs = [nArgs]() -> int {return nArgs; };
//pour l’appeler :
std::cout << getArgs() << std::endl;
On peut aussi la déclarer comme ça :
PHP:
auto args = [nArgs]() {return nArgs; };
Différentes options pour la capture list :
/!\ Les variables capturées par valeur ont la valeur qu'ils avaient au moment ou la lambda a été crée, et pas quand elle est exécutée ! (mauvais souvenirs avec LINQ en C#, je préfère prévenir ...)
- [] : Vide, aucune variable locale utilisée.
- [names] Capture par valeur, il faut ajouter un '&' devant le nom de la variable pour capturer par référence.
- [&] Capture toute les variables par référence.
- [=] Capture toute les variables par valeur.
- [&,liste] Capture tout par référence sauf les variables qui sont dans la liste, elles seront capturée par valeur.
- [=,liste] Capture tout par valeur sauf les variables qui sont dans la liste, elles seront capturée par référence.
Exemple avec des algorithmes
Disons qu'on a un std::vector, comme celui ci :
PHP:
std::vector<int> vec;
for (int i = 0; i != 10; i++)
vec.push_back(i);
Maintenant on veut pouvoir afficher chaque élément sur notre console, ce qui vous vient en tête :
PHP:
// j'utilise un std::vector<int>::const_iterator vu qu'on ne modifie rien
for (auto it = vec.cbegin(); it != vec.cend(); it++)
std::cout << *it << std::endl;
Mais il y a un moyen plus simple (IMO), utiliser l'algorithme std::for_each !
PHP:
std::for_each(vec.cbegin(), vec.cend(), [] (int val)
{
std::cout << val << std::endl;
});
Comment ça fonctionne, demandez vous ? En fait, std::foreach va appeler notre lambda pour chaque élément qui est dans le vector.
PHP:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
{
while (first!=last) {
fn (*first); // ICI
++first;
}
return fn; // or, since C++11: return move(fn);
}
Épilogue
Voila, ce tutoriel est termine, je sais que les exemples que j'ai utiliser ne sont pas terribles, mais il y a vraiment beaucoup de choses possibles avec ces lambdas ! J'ajouterais peut être une partie sur std::bind & std::placeholders plus tard.
En attendent si vous avez des questions n’hésitez pas a les poser ;)
Cordialement, Davy.