Les Lambdas sont syntatic de sucre pour un innommable de la classe et de l'instance de celle-ci. Parfois, l'expansion de votre code pour que cette innommable de la classe peut aider à comprendre ce qui se passe.
[ capture_list ]( arg_list ) -> return_value_clause_opt { body };
devient très grossièrement (pseudo-code):
struct anonymous_type {
capture_list;
auto operator()( arg_list ) const -> return_value_clause_opt {
body
}
anonymous_type( capture_list_in ):capture_list(capture_list_in) {}
};
Si vous indiquez une variable en capture_list
par le simple nom, il est copié dans une copie au sein de la classe anonyme.
Si votre timesFive
est devenu
struct __secret_name__ {
int multiplier;
int operator()(int a) const { return a*multiplier; }
};
int multiplier = 5;
auto timesFive = __secret_name__{multiplier};
Il devrait être assez évident que l'évolution multiplier
dans le code ci-dessus ne changent pas le comportement de l' timesFive
.
Si vous mettez un &
devant le nom, un non-const
de référence est placé à l'intérieur de la classe anonyme.
struct __secret_name__ {
int& multiplier;
int operator()(int a) const { return a*multiplier; }
};
int multiplier = 5;
auto timesFive = __secret_name__{multiplier};
maintenant, l'évolution multiplier
va modifier le comportement de l' timesFive
car timesFive
détient une référence de multiplicateur, pas une copie.
Quelques détails sauté dessus pour des raisons de concision. Le nom de l' __secret_name__
seulement pour l'exposition. Les variables membres de l'lamba ne sont pas réellement public. Le lambda étant trivialement constructible est de la mise en œuvre définies, même si ses données. Etc.