【C++学习笔记】lambda表达式的mutable

  • mutable修饰符用来指明我们可以对const的变量进行修改,同样,在lambda函数中,也可以使用此修饰符。
  1. 按值捕获到lambda函数中的变量在函数体中默认是const类型,即不可修改,在添加了mutable修饰符后,便可以对此变量进行修改,但此时仍然修改的是位于lambda函数体中的局部变量,具体的用处类似于函数体中的static变量,只允许在该函数中改变。
    这是由于lambda函数其实也是一种类,然后下面这个初始化语句:
    auto f=[v1](A a) mutable -> B{...}
    实际上一方面定义了一种返回值为B,接收一个A类型参数的,这样的lambda函数类型。一方面也定义了一个这样的lambda函数对象 f, 所以此处在捕获变量列表中值捕获的变量v1,它其实可以被看做对象f的一个数据成员变量,其初始值为9,因此,函数体内对其每次的变动都会被累积。
int n {};
// 使用mutable时,参数列表“()”是不可以省略的
auto fun = [n] () mutable {
	return ++n;
};

cout<<fun() <<endl;
cout<<fun() <<endl;

/** Output
  * 1
  * 2
  */
  1. 还有一种情况就是当使用匿名的lambda表达式的时候是不会有这种保留改动的现象的。
int n {};
for(int i=3; i>0; i--){
	[n] () mutable {
		n++;
		cout<<n <<endl;
	}();
}

/** Output
  * 1
  * 1
  * 1
  */

这是因为,lambda其实相当于是一个匿名类,原理还是利用其operator(),1 中匿名类被赋值给fun,[]捕获列表相当于给这个类添加了一个静态成员变量,因此每次调用都会+1;而 2 中是在for的函数体内构建lambda表达式,每次进入for都会重新构建一个匿名类,出了for的局部作用域销毁,因此每次都是 1,不会+1。

你可能感兴趣的:(C++,c++,学习,开发语言)