您的位置:首页 > 编程语言 > C语言/C++

C++ 11 之Lambda

2017-05-07 10:35 260 查看
1.Lambda表达式来源于函数式编程,说白就了就是在使用的地方定义函数,有的语言叫“闭包”,如果 lambda 函数没有传回值(例如 void ),其回返类型可被完全忽略。 定义在与 lambda 函数相同作用域的变量参考也可以被使用。这种的变量集合一般被称作 closure(闭包);

2.简单语法:

[capture](parameters)->return_type {body}

[函数对象参数](操作符重载函数参数)->返回值类型{函数体}

函数对象参数规则(capture):

 [] 不捕获任何变量

 [&] 以引用方式捕获所有变量

 [=] 用值的方式捕获所有变量(可能被编译器优化为const &)

[=, &foo] 以引用捕获foo, 但其余变量都靠值捕获

[bar] 以值方式捕获bar; 不捕获其它变量

[this] 捕获所在类的this指针

 
3.例子:

int main()
{
char s[] = "hEllo, C++";
int Upper = 0;  //通过lambda修改

for_each(s, s + sizeof(s), [&Upper](char c)
{if (isupper(c)) Upper++; });

cout << Upper << " uppercase letters in: " << s << endl;

return 0;
}
注解:其中 [&Uppercase] 中的 & 的意义是 lambda 函数体要获取一个 Uppercase 引用,以便能够改变它的值,如果没有 &,那就 Uppercase 将以传值的形式传递过去。

1 vector<int> iv{5, 4, 3, 2, 1};
2 int a = 2, b = 1;
3 for_each(iv.begin(), iv.end(), [b](int &x){cout<<(x + b)<<endl;}); // (1)
4 for_each(iv.begin(), iv.end(), [=](int &x){x *= (a + b);});        // (2)
5 for_each(iv.begin(), iv.end(), [=](int &x)->int{return x * (a + b);});// (3)
注解:

[]内的参数指的是Lambda表达式可以取得的全局变量。(1)函数中的b就是指函数可以得到在Lambda表达式外的全局变量,如果在[]中传入=的话,即是可以取得所有的外部变量,如(2)和(3)Lambda表达式()内的参数是每次调用函数时传入的参数。->后加上的是Lambda表达式返回值的类型,如(3)中返回了一个int类型的变量

4.扩展

在传统的STL中for_each() 这个玩意最后那个参数需要一个“函数对象”,所谓函数对象,其实是一个class,这个class重载了operator(),于是这个对象可以像函数的式样的使用。实现一个函数对象并不容易,需要使用template,比如下面这个例子就是函数对象的简单例子(实际的实现远比这个复杂):

template <class T>
class less
{
public:
bool operator()(const T&l, const T&r)const
{
return l < r;
}
};
5.原因 C++引入Lambda的最主要原因就是:1)可以定义匿名函数。2)编译器会把其转成函数对象。

疑问为什么以前STL中的ptr_fun()这个函数对象不能用?(ptr_fun()就是把一个自然函数转成函数对象的)。原因是,ptr_fun() 的局限是其接收的自然函数只能有1或2个参数。

那么,除了方便外,为什么一定要使用Lambda呢?它比传统的函数或是函数对象有什么好处呢?我个人所理解的是,这种函数之年以叫“闭包”,就是因为其限制了别人的访问,更私有。也可以认为他是一次性的方法。Lambda表达式应该是简洁的,极私有的,为了更易的代码和更方便的编程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lambda C++11