试图了解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。 等等。