那么什么是编程语言中的闭包呢?我是一头雾水,网络达人有语:“外事不明问谷歌,内事不明问百度!”,英语向来差劲的在下,就先去找度娘商议了一番,度娘给出如下回答:
闭包是可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境 (作用域)。在 Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby 和 Python,objective c 等语言中都能找到对闭包不同程度的支持。
度娘向来如此文艺,说的我是一知半解,到底神马意思呢?
我们还是举个例子来表达之:
点击(此处)折叠或打开
-
/*************************************************************************
-
> File Name: lambda.cpp
-
> Author: dongdaoxiang
-
> Mail: dongdaoxiang@ncic.ac.cn
-
> Created Time: 2013年03月19日 星期二 11时31分42秒
-
************************************************************************/
-
-
#include<iostream>
-
#include<vector>
-
using namespace std;
-
int main()
-
{
-
int temp = 10;
-
vector<int> ivec = {30, -10, -20, 50, 40 ,100, -50};
-
vector
::iterator it = ivec.begin();
while(it != ivec.end())
{
cout << *it << endl;
it++;
}
-
return 0;
- }
1、代码的复用性不强,如果下次我们还要遍历另外的一个容器的时候,我们还要重复这里我们的工作。
2、这样写起来太繁琐。
这个时候,有人举手了!说我门可以使用c++的algorithm库内的函数来完成我们操作!于是乎就有了下面的代码:
点击(此处)折叠或打开
-
/*************************************************************************
-
> File Name: lambda.cpp
-
> Author: dongdaoxiang
-
> Mail: dongdaoxiang@ncic.ac.cn
-
> Created Time: 2013年03月19日 星期二 11时31分42秒
-
************************************************************************/
-
-
#include<iostream>
-
#include<vector>
-
#include<algorithm>
-
using namespace std;
-
class printInt
-
{
-
public:
-
void operator()(const int x)
-
{
-
cout << x << endl;
-
}
-
};
-
-
int main()
-
{
-
int temp = 10;
-
vector<int> ivec = {30, -10, -20, 50, 40 ,100, -50};
-
std::for_each(ivec.begin(), ivec.end(), printInt());
-
return 0;
- }
点击(此处)折叠或打开
-
#include<iostream>
-
#include<vector>
-
#include<algorithm>
-
using namespace std;
-
class printInt
-
{
-
public:
-
void operator()(const int x)
-
{
-
cout << x << endl;
-
}
-
};
-
-
int main()
-
{
-
int temp = 10;
-
vector<int> ivec = {30, -10, -20, 50, 40 ,100, -50};
-
std::sort(ivec.begin(), ivec.end());
-
std::for_each(ivec.begin(), ivec.end(), printInt());
-
return 0;
- }
点击(此处)折叠或打开
-
#include<iostream>
-
#include<vector>
-
#include<algorithm>
-
using namespace std;
-
void abs_sort(vector<int> &ivec, int i, int j )
-
{
-
if(i < j)
-
{
-
int left = i;
-
int right = j;
-
int rawData = ivec[left];
-
int flag = abs(ivec[left]);
-
while(left < right)
-
{
-
while(left < right && abs(ivec[right]) > flag)
-
{
-
right--;
-
}
-
ivec[left] = ivec[right];
-
while(left < right && abs(ivec[left]) <= flag)
-
{
-
left++;
-
}
-
ivec[right] = ivec[left];
-
}
-
ivec[left] = rawData;
-
abs_sort(ivec, i, left - 1);
-
abs_sort(ivec, left + 1, j);
-
}
-
}
-
class printInt
-
{
-
public:
-
void operator()(const int x)
-
{
-
cout << x << endl;
-
}
-
};
-
-
int main()
-
{
-
int temp = 10;
-
vector<int> ivec = {30, -10, -20, 50, 40 ,100, -50};
-
//std::sort(ivec.begin(), ivec.end());
- abs_sort(ivec, 0, ivec.size() - 1);
-
vector
::iterator it = ivec.begin(); -
while(it != ivec.end())
{ -
*it += temp;
cout << *it << endl;
it++;
} -
return 0;
- }
点击(此处)折叠或打开
-
/*************************************************************************
-
> File Name: lambda.cpp
-
> Author: dongdaoxiang
-
> Mail: dongdaoxiang@ncic.ac.cn
-
> Created Time: 2013年03月19日 星期二 11时31分42秒
-
************************************************************************/
-
-
#include<iostream>
-
#include<vector>
-
#include<algorithm>
-
using namespace std;
-
-
int main()
-
{
-
int temp = 10;
-
vector<int> ivec = {30, -10, -20, 50, 40 ,100, -50};
-
std::sort(ivec.begin(), ivec.end(), [](const int &x, const int &y) {return abs(x) < abs(y);});
-
std::for_each(ivec.begin(), ivec.end(), [&](int &x) { x += temp; cout << x << endl;});
-
return 0;
- }
Lambda表达式是一种描述函数对象的机制,它的主要应用是描述某些具有简单行为的函数(译注:Lambda表达式也可以称为匿名函数,具有复杂行为的函数可以采用命名函数对象,当然,简单和复杂之间的划分依赖于编程人员的选择)。
上面的例子中参数 [](const int &x, const int &y) { return abs(x) < abs(y); }是一个"lambda"(又称为"lambda函数"或者"lambda表达式"), 它描述了这样一个函数操作:接受两个整形参数a和b,然后返回对它们的绝对值进行"<"比较的结果。
[&] 是一个“捕捉列表(capture list)”,用于描述将要被lambda函数以引用传参方式使用的局部变量。如果我们仅想“捕捉"参数v,则可以写为: [&v]。而如果我们想以传值方式使用参数v,则可以写为:[=v]。如果什么都不捕捉,则为:[]。将所有的变量以引用传递方式使用时采用 [&], [=] 则相应地表示以传值方式使用所有变量。(译注:“所有变量”即指lambda表达式在被调用处,所能见到的所有局部变量)
这意味着什么,我们不用向以前c语言中的高阶函数那样,通过函数指针来传递函数的操作了,而指针的操作往往就是c/c++中99%的坑的来源!他可以在局部大函数里面访问环境中的局部变量,多么cool和powerful的功能!
为了描述一个lambda,你必须提供:
- 它的捕捉列表:它可以使用的变量列表(除了形参之外),如果存在的话("[&]" 在上面的记录比较例子中意味着“所有的局部变量都将按照引用的方式进行传递”)。如果不需要捕捉任何变量,则使用 []。
- (可选的)它的所有参数及其类型(例如: (int a, int b) )。
- 组织成一个块的函数行为(例如:{ return v[a].name < v[b].name; })。
- (可选的)采用了新的后缀返回类型符号的返回类型。但典型情况下,我们仅从return语句中去推断返回类型,如果没有返回任何值,则推断为void。
总结一下吧:本文简单的介绍了一下对于c11标准中新增的lambda表达的式的一些个看法,完全出自一家之言,如有不恰当的地方欢迎批评指正,如有雷同实属巧合!!
本文参考一下前辈的博文: