试图了解lambda

试图理解C ++中的lambdas,我不明白的是:

int multiplier = 5; auto timesFive = [multiplier](int a) { return a * multiplier; }; std::cout << timesFive(2) << '\n'; // Prints 10 multiplier = 15; std::cout << timesFive(2) << '\n'; // Still prints 2*5 == 10 (???) - Should it be 30? 

当程序第二次调用timesFive()时,我期望结果是30.但为什么结果Still prints 2*5 == 10 ,而不prints 2*15 == 30 ? 也许lambda函数不能跟踪multiplier的值,尽pipe我们已经试图捕获它了?

怎样才能得到理想的结果?

你通过值捕获multiplier ,这意味着它被复制到lambda中。 你需要通过引用来捕获它:

 int multiplier = 5; auto timesFive = [&multiplier](int a) { return a * multiplier; }; std::cout << timesFive(2); multiplier = 15; std::cout << timesFive(2); 

兰姆达斯是一个不可思议的类和它的例子syntally糖。 有时将代码扩展到这个不可理解的类可以帮助理解正在发生的事情。

 [ capture_list ]( arg_list ) -> return_value_clause_opt { body }; 

变得非常粗略(伪代码):

 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) {} }; 

如果您用简单名称在capture_list列出了一个variables,它将被复制到匿名类中的一个副本中。

所以你的时间timesFive

 struct __secret_name__ { int multiplier; int operator()(int a) const { return a*multiplier; } }; int multiplier = 5; auto timesFive = __secret_name__{multiplier}; 

应该很清楚,在上面的代码中改变multiplier不会改变timesFive的行为。

如果在名称的前面放置一个& ,则在匿名类中放置一个非const 引用

 struct __secret_name__ { int& multiplier; int operator()(int a) const { return a*multiplier; } }; int multiplier = 5; auto timesFive = __secret_name__{multiplier}; 

现在,改变multiplier会改变时间的行为timesFive ,因为timesFive一个乘数的参考 ,而不是它的副本。


为简洁起见,上面略过了一些细节。 名称__secret_name__仅用于说明。 lamba的成员variables实际上并不公开。 即使其数据是可执行定义的,也是可以构造的lambda。 等等。