27 votes

Quel est le but de spécifier une variable capturée dans une expression lambda ?

J'ai ce code :

int i = 0;
[&i](){i++;}();

Mais je peux omettre le i et juste utiliser :

[&](){i++;}();

Quel est le but de spécifier &i ? (et de la même manière =var et = ). Cela affecte-t-il les performances à la compilation ou à l'exécution ?

26voto

Nawaz Points 148870

&i signifie seulement i est capturé comme référence, tandis que & signifie que toutes les variables qui sont utilisées dans le lambda, sont capturées à partir de la portée.

int i = 0, j = 10;

[&i]{ i++; j++;}(); //error: j is not captured by reference

[&]{ i++; j++;}(); //ok: both variables are captured by reference

Le site &i L'approche est fournie par la langue pour limite la quantité de variables capturées. C++ vous offre un contrôle total sur les variables capturées, comme par exemple sur les variables suivantes spécifique les variables à capturer, comment les capturer (par valeur, ou par référence).

Même raisonnement avec i et = :

int i = 0, j = 10;

[i]{ i++; j++;}(); //error: j is not captured (only i is captured by value)

[=]{ i++; j++;}(); //ok: both variables are captured by value

//more
[&i, j]{ i++; j++;}(); //ok: captured i by reference, j by value

J'espère que cela vous aidera.

21voto

Timothy Shields Points 17970

Parfois, vous pouvez vouloir capturer différentes variables de différentes manières :

std::vector<int> v { 7, 8, 9, 10, 11 };
int n = 3;

//Capture v by reference and n by value:
auto getNth = [&v, n](){ return v[n]; };

//Behavior:
n = 9999;
getNth(); //returns 10 - changing n didn't affect the lambda
v[3] = 42;
getNth(); //returns 42 - changing v did affect the lambda

C'est pourquoi la syntaxe plus détaillée est disponible.

17voto

JaredPar Points 333733

Cette fonctionnalité n'est pas une question de performances, mais de lisibilité et de facilité de maintenance. Lorsque vous utilisez la syntaxe de capture de couverture [&] ou [=] alors il obscurcit l'état qui est partagé entre la méthode originale et le corps lambda. Cela peut contribuer à des problèmes de maintenance dans une méthode si un dev suppose à tort qu'une valeur n'est pas capturée alors qu'elle l'est. Le fait d'avoir une clause de capture rend beaucoup plus explicite l'état sur lequel la lambda s'appuie.

11voto

Reed Copsey Points 315315

Quel est l'intérêt de spécifier &i ? (et de la même manière =var et =). Cela affecte-t-il les performances à la compilation ou à l'exécution ?

Vous pouvez spécifier si les valeurs sont capturées par référence ou par valeur. Utilisation de [&] spécifie que vous voulez tout capturer par référence, mais vous pouvez aussi écrire une lambda qui le fait :

[=, &i, &j]()

Ce qui veut dire qu'il faut tout saisir par la valeur, sauf capture i et j par référence.

Dans votre cas spécifique, cela n'est pas utile - vous pouvez simplement dire que vous capturez tout par référence, et le compilateur déterminera que vous utilisez i Mais lorsqu'il s'agit de capturer plusieurs variables, le C++ vous permet de contrôler la façon dont chaque variable est capturée individuellement.

4voto

Angew Points 53063

Si vous dressez la liste des variables à capturer, vous êtes explicite dans ce que vous voulez. Et vous obtenez une erreur du compilateur au cas où vous utilisez quelque chose que vous ne vouliez pas (vous ne l'avez pas capturé). Cela peut être une bonne chose (vous avez fait une véritable erreur dans l'implémentation) ou une mauvaise chose (vous avez juste oublié de lister la variable).

Cela dépend vraiment du scénario particulier. Je dirais que plus la lambda est complexe et/ou plus la portée contenue est complexe, plus il est préférable d'être explicite sur ce que vous capturez.

Il y a un point supplémentaire, et c'est le mélange de la capture par valeur et de la capture par référence - vous devez être explicite dans au moins l'un des deux. Exemple :

int i, j, k;

auto f = [=, &i]() { /* code which can read i, j and k but can only modify i */ };

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X