本文共 2433 字,大约阅读时间需要 8 分钟。
微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!点击上方蓝字关注我,我们一起学编程
有任何疑问或者想看的内容,欢迎私信
微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!常见的两个可调用对象是函数和函数指针。所谓可调用对象,就是可以对齐使用**调用运算符()
**的对象。下面我们介绍一种 C++11 新标准引入的一种新的可调用对象——lambda 表达式。
一般形式:
[捕获列表] (参数列表) -> 返回值类型 { 函数体 }
其中:捕获列表是一个 lambda 所在函数中定义的局部变量的列表。也就是这个 lambda 表达式所在作用域中的局部变量。参数列表、返回值类型和函数体与普通函数相同。
一个 lambda 表达式最少含有:
[捕获列表] { 函数体 }
auto func = [] { return 1;};cout << func() << endl; // 1
微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!向 lambda 传递参数:
auto func = [] (int a, int b) -> bool { return a < b; };cout << func(1, 2) << endl; // true
使用捕获列表:
先来看一个简单的例子:
#includeusing namespace std;int main(){ int a = 1; auto sum = [a] (int b) -> int { return a + b; }; cout << sum(2) << endl; // 3 return 0;}
上面的例子中,lambda 表达式捕获了其作用域中的另一个局部变量 a
,并在其函数体中使用了该局部变量。
类似于参数传递,变量的捕获方式也有“值”和“引用”两种方式。
值捕获:
值捕获中的变量拷贝是发生在创建 lambda 时,而非调用时。
#includeusing namespace std;int main(){ int a = 1; auto func = [a] { cout << a << endl; }; a = 2; func(); // 1 return 0;}
引用捕获:
#includeusing namespace std;int main(){ int a = 1; auto func = [&a] { cout << a << endl; }; a = 2; func(); // 2 return 0;}
微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!隐式捕获:
上面列出的几种捕获方式都是显式捕获,我们也可以使用隐式捕获,让编译器根据 lambda 函数体来自动推断我们要使用哪些变量。在捕获列表中输入 =
表示值捕获,&
表示引用捕获。
#includeusing namespace std;int main(){ int a = 1; auto func1 = [=] { cout << a << endl; }; auto func2 = [&] { cout << a << endl; }; a = 2; func1(); // 1 func2(); // 2 return 0;}
可变 lambda :
对于一个值捕获的局部变量,lambda 是不会改变其值的。
#includeusing namespace std;int main(){ int a = 1; auto func = [=] { a = 2; }; func(); return 0;}/*编译报错:error: increment of read-only variable ‘a’*/
微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!如果我们希望能改变一个被捕获的变量的值,一种方法是使用引用捕获,另一种方法是使用关键字 mutable
。
#includeusing namespace std;int main(){ int a = 1; auto func = [=] () mutable{ cout << ++a << endl; }; func(); // 2 cout << a << endl; // 1 return 0;}
我们还注意到,虽然在 lambda 表达式中修改了捕获的局部变量的值,但外部的局部变量并未收到影响。但引用捕获的方式则相反。
#includeusing namespace std;int main(){ int a = 1; auto func = [&] () { cout << ++a << endl; }; func(); // 2 cout << a << endl; // 2 return 0;}
捕获列表:
[]
空捕获列表,lambda 不能使用所在函数中的任何变量。[names]
names 是一个使用逗号分隔的名字列表,lambda 可以使用这些局部变量,默认为值捕获。[=]
隐式值捕获,lambda 可以使用所在函数中的所有局部变量。[&]
隐式引用捕获,lambda 可以使用所在函数中的所有局部变量。上面的几种方式可以混合使用。
微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!转载地址:http://gqkgn.baihongyu.com/