c++ lambda函数 及 mutable
mutable修饰符用来指明我们可以对const的变量进行修改,同样,在lambda函数中,也可以使用此修饰符。
按值捕获到lambda函数中的变量在函数体中默认是const类型,即不可修改,在添加了mutable修饰符后,便可以对此变量进行修改,但此时仍然修改的是位于lambda函数体中的局部变量,具体的用处类似于函数体中的static变量,只允许在该函数中改变。
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的输出。
还有一种情况就是当使用匿名的lambda表达式的时候是不会有这种保留改动的现象的。
int n {};
for(int i=3; i>0; i--){
[n] () mutable {
n++;
cout<<n <<endl;
}();
}
/** Output
* 1
* 1
* 1
*/
在上述例子中由于在循环体中定义了一个匿名的lambda函数,因此每次循环对变量n
做出的改变都不会得到保留,因而每次循环都相当于是一个新的捕获。
上述的观点可以在如下几个示例中看出。
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
*/