C++11中,Lambda表达式是最常用的特性之一,有过java、python以及C#开发经验的人对lambda功能都不会陌生。lambda表达式来源于函数式编程,具备以下优点:
lambda表达式概念和语法lambda实际上是一个匿名函数,运行时能够捕获到程序范围内的变量,其定义方式如下:
[capture] (params) opt -> ret {body;} ;
在上面的定义中,capture可以根据不同的取值,捕获不同范围内的变量,具体如下:
capture形式 | 说明 |
---|---|
[] | 不捕获变量 |
[&] | 引用捕获,捕获所有变量 |
[=] | 按值捕获,捕获所有变量 |
[=,&foo] | 按值捕获所有变量,按引用捕获foo变量 |
[foo] | 按值捕获foo,不捕获其他变量 |
[this] | 捕获类中的this指针 |
params是参数列表;opt是函数选项;ret是返回值类型;body是函数体,当然在实际的使用中,lambda表达式也可以省略函数返回值的定义。省略函数返回值的lambda表达式定义可以参考下面的示例:
auto fr = [](int a) { return (a+1); };
上面的代码在编译时,编译器会根据return的语句进行自动推导。lambda表达式按值捕获参数时是不能够修改捕获的变量的,如果要进行修改,改如何做?
如何修改按值捕获的变量?在使用lambda表达式时,如果使用按址引用,可以修改捕获的变量,如果是按值捕获同时又要修改变量时需要在定义时使用mutable关键字,而且要进行显示说明,如:
int a = 0;
auto fr = [=]() mutable {return a++;};
在这里需要提醒大家,如果要在lambda表达式中使用mutable,不管表达式中有没有参数选项,都要把参数列表加上。
由此可见:mutable的作用就要要取消const的作用。
lambda表达式和std::function配合使用在C++11中,lambda表达式类型有叫做“闭包类型”。
可以认为是一个带有operator()的类,于是可以将其和function配合使用,使用方法如下:
std::function<int(int)> fr = [](int a) {return a; };
同理,也可以和std::bind配合使用,只要将上面的代码稍作修改即可完成,具体如下:
std::function<int(void)> fr = std::bind([](int a) {return a; },123);
std::cout<<"fr()="<<fr()<<std::end;
如上:函数输出值为:123最后,以一个lambda的例子结束本文:
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
int main()
{
std::vector<int> c { 1,2,3,4,5,6,7 };
int x = 5;
c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());
std::cout << "c: ";
for (auto i: c) {
std::cout << i << ' ';
}
std::cout << '\n';
// the type of a closure cannot be named, but can be inferred with auto
auto func1 = [](int i) { return i+4; };
std::cout << "func1: " << func1(6) << '\n';
// like all callable objects, closures can be captured in std::function
// (this may incur unnecessary overhead)
std::function<int(int)> func2 = [](int i) { return i+4; };
std::cout << "func2: " << func2(6) << '\n';
}
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8