c++中的lambda表达式
随着vs2010的推出,c++有了更多的特性,其中最诱人的就是lambda表达式的引入了。lambda表达式也就是匿名函数,和c#中的lambda表达式是同一个意思,不过在c++中他的写法有点不一样,下面我就来介绍c++中lambda表达式的格式。
首先让我们看一下msdn上的例子:
// lambda_structure.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
// The number of elements in the vector.
const int elementCount = 9;
int main()
{
// Create a vector object with each element set to 1.创建数组,并初始化为全1.
vector<int> v(elementCount, 1);
// These variables hold the previous two elements of the vector.
int x = 1;
int y = 1;
// Assign each element in the vector to the sum of the
// previous two elements.使用lambda对数组赋值,每一项的值为前两项的和。
generate_n(v.begin() + 2, elementCount - 2, [=]() mutable throw() -> int {
// Generate current value.临时变量n
int n = x + y;
// Update previous two values.求和。
x = y;
y = n;
return n;//输出。
});
// Print the contents of the vector.利用lambda打印数组。
for_each(v.begin(), v.end(), [](int n) { cout << n << " "; });
cout << endl;
// Print the local variables x and y.
// The values of x and y hold their initial values because
// they are captured by value.
cout << x << " " << y << endl;
}
这是一个数组赋值的例子,里面有两个lambda表达式,我们先对第一个进行分析。 这是一个基本的lambda表达式,其中各部分为:
- lambda标志;
- lambda参数声明;
- 特殊属性参数;
- 异常定义;
- lambda返回值类型定义;
- 函数体;
第1部分中的[]可以理解为lambda的起始标示符,标志着下面的程序是lambda表达式。里面的符号说明的是在函数体内所用的外部变量的传值类型,=是以值(value)的类型传递,在函数体内出现的外部变量是只读的;&是以引用(reference)的类型传递,在函数体内出现的外部变量名就相当于他们的别名,这个和一般函数以引用的形式传形参是一样的。当然你也可以自己定义哪些参数是引用传递哪些是值传递,写法如下:
[&total, factor]
[&, factor]
[=, &total]
上面三个形式产生的效果是一样的,当第一个参数为=或&时表示其他参数都是以=或&形式传递,除了特别标出的外。
第2部分是lambda参数声明,也就是一般函数的形参表,具体的就不说了。
第3、4部分都是lambda的特殊属性参数,扩展lambda的功能。其中mutable表示在函数体内lambda将拷贝一份所用到的外部变量,它与外部的变量值一样,且可以改变,但并不能改变外部变量。throw()是异常的定义,表示可以在lambda表达式内抛出异常,具体可以参考异常的用法。
第5部分是定义返回的值类型,就相当于一般函数头开始的返回类型定义,不过他这写法比较特殊,前面要加->符号,如果函数没有值返回可以留空。
最后一部分是函数体,这个大家应该都懂的。
第二个lambda表达式是作为输出用的,刚好和第一个相反,他是带形参的,也就是(int n)这部分。函数体内没有使用外部变量所以[]部分留空,没返回值->部分可以不写,函数体内是输出部分,每个变量依次打印出来,结果如下图。
最后显示了x和y的值,可以看到虽然x、y在第一个lambda里面被改变了,但最后输出的还是一开始的值,这也就是mutable的作用。
我所了解的就这些,还有很多高级的写法现在还没掌握,讲的不好请多包涵。