【C++学习笔记】C++ lambda函数 及mutable

  • mutable修饰符用来指明我们可以对const的变量进行修改,同样,在lambda函数中,也可以使用此修饰符。
  1. 按值捕获到lambda函数中的变量在函数体中默认是const类型,即不可修改,在添加了mutable修饰符后,便可以对此变量进行修改,但此时仍然修改的是位于lambda函数体中的局部变量。
int n {};
// 使用mutable时,参数列表“()”是不可以省略的
auto fun = [n] () mutable {
	return ++n;
};

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

/** Output
  * 1
  * 2
  */

在上述例子中,auto fun = …相当于定义了一个lambda对象,该对象有一个外部捕获的可修改的成员n,对fun对象的每次修改都会使得改变被保留在fun对象内部。因而可以得到n是1、2的输出。

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

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

在上述例子中由于在循环体中定义了一个匿名的lambda函数,因此每次循环对变量n做出的改变都不会得到保留,因而每次循环都相当于是一个新的捕获。

  1. 上述的观点可以在如下几个示例中看出。
int n {};
auto fun = [n] () mutable {
	return ++n;
};

for(int i=3; i>0; i--){
	cout<<fun() <<endl;
}

/** Output
  * 1
  * 2
  * 3
  */

for(int i=2; i>0; i--){
	int n {};
	auto funs = [n] () mutable {
		return ++n;
	};

	cout<<funs() <<endl;
	cout<<funs() <<endl;
}

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

for(int i=2; i>0; i--){
	int n {};
	[n] () mutable {
		cout<< ++n <<endl;
	};

	[n] () mutable {
		cout<< ++n <<endl;
	};
}

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

你可能感兴趣的:(C++,C++)