Pages

lundi 10 décembre 2012

Les lambdas en C++

Les lambdas ou fonctions anonymes sont un mécanisme présent dans beaucoup de langages de programmation, C++11 en fait partie :).

Le principe est simple, créer un foncteur à la volée pour le passer directement à une fonction/classe ou le stocker dans une variable. Par exemple, dans mon précédant billet sur le C++, la variable f contient une lambda.

La plus courte et inutile lambda existante fait 4 caractères, ce sont les 4 caractères obligatoires à la création d'une lambda : []{}

La syntaxe complète est celle-ci :
[clause-de-capture](paramètres...) mutable-specification exception-specification -> type-de-retour { corps-du-lambda }
Ce qui fait 6 parties

Clause de capture

[clause-de-capture]: spécifie comment l'expression lambda accède aux variables dans la portée englobante. Par défaut, aucune variable n'est accessible.
Un & indique un accès par référence et un = par valeur.
Si la & est préfixée d'un nom de variable, alors seule cette variable est accessible par référence.
Si le nom de variable n'est pas préfixé alors la variable est accessible par valeur.
Pour finir, la clause this permet d’accéder au scope de la classe (si créé dans une classe, évidemment).
Bien sûr, plusieurs clauses peuvent être indiquées en les séparant par des virgules.

  • [=] tous par valeur
  • [&] tous par référence
  • [x] x par valeur
  • [&x] x par référence
  • [&, x] x par valeur, tout le reste par référence
  • [=, &x] x par référence, tout le reste par valeur
  • [this] permet d'utiliser le pointeur this

Liste de paramètres

(paramètres...): Pareil que pour une fonction mais pas de template. En c++14, les types peuvent être auto pour remplacer les templates.
Facultative si mutable-specification, exception-specification et type-de-retour ne sont pas indiqués.

Spécification mutable

mutable: Permet de modifier les variables qui sont capturées par valeur.

[=](){++x} // erreur car x est en lecture seule
[=]() mutable {++x} // ok

Spécification d'exception

noexcept: Là rien d'extraordinaire, on l'indique si aucune exception n'est retournée.

Type de retour

-> type-de-retour: Indique le type de retour. Optionnel, le compilateur utilisant automatiquement un decltype.

Corps du lambda

{ corps-du-lambda }: le super algorithme de la mort qui tue.
À noter que les variables globales et statiques sont accessibles.

Aucun commentaire: