C++11添加了一项名为lambda表达式的新功能,通过这项功能可以编写内嵌的匿名函数,而不必编写独立函数和函数对象。
下面看看它的结构组成:
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
[[&k, j] | (int a, int b) | mutable | throw | -> int | {int m = a + b + k + j; k++; j++ return m;} | (1, 2) |
- Capture 子句([]内部可为空,此时不捕获周围变量,“&”表示引用变量,“=”表示复制变量)
- 参数列表(可选) (也称为 lambda 声明符)
- 可变规范(可选)(使用 mutable 后,lambda表达式将可以改变捕获到的变量)
- 异常规范(可选)
- 尾随返回类型(可选)
- “lambda 体”
- 初始化列表(可选)(它使得表达式立即执行)
最简单的列子:
auto a = []{return 5;};
上面的例子还没有什么使用价值。下面再来个:
std::string result=[](const std::string& str)->std::string{return "Hello from "+str;}("second Lambda");
输出如下所示:
Hello from second Lambda
该lambda表达式接受一个string参数并返回一个string,结果保存在变量result中,尾部的括号使得该表达式立即执行。
再来一个:
#include <iostream>
#include <algorithm>
#include <vector>
auto main(int argc, char** argv) -> int
{
std::vector<int> vec={1, 2, 3, 4, 5, 6, 7, 8, 9};
int value=3;
int cnt=std::count_if(vec.cbegin(), vec.cend(), [=](int i){return i>value;});
std::cout<<"Found "<<cnt<<" values > "<<value<<std::endl;
return 0;
}
输出如下所示:
Found 6 values > 3
通过count_if算法计算vector中满足特定条件的元素个数,lambda表达式的形式给出了条件,注意表达式中的=,等号表示通过值捕捉所在作用域的变量,这个例子中捕捉的是value的值。前面的例子[]为空,即捕捉块为空,那么在lambda表达式的主体body内就无法访问变量了。以下是关于捕捉块的详细介绍:
[=]通过值捕捉所有变量
[&]通过引用捕捉所有变量
[value]通过值捕捉value,不捕捉其它变量
[&value]通过引用捕捉value,不捕捉其它变量
[=, &value]默认通过值捕捉,变量value例外,通过引用捕捉
[&, value]默认通过引用捕捉,变量value例外,通过值捕捉