一、什么是匿名函数
匿名函数是许多编程语言都支持的概念,有函数体,没有函数名。
C++中的匿名函数,类似于python的lambda函数,也就是在句中定义和声明的一个临时函数,仅在调用时才会创建函数对象,无需在头文件中声明。
二、匿名函数的形式
capture->return-type{body}
捕获列表->返回类型-{函数主体}
capture:捕获列表
- [] //捕获列表为空。在函数内无法使用外部变量。
- [a] //捕获列表为按值传递形式。在函数内仅能使用传递的变量值,无法改变变量。值在匿名函数生成时便已经确定,后续修改不会影响函数内的变量值。
- [&a] //按应用传递。可改变变量。
- return-type:返回类型
一般情况下编译器可以推断出返回类型,可以用auto而不指定返回类型。但有多个return语句时需要指定返回类型。
Lambda 表达式函数的捕捉列表
[] 不截取任何变量
[&} 截取外部作用域中所有变量,并作为引用在函数体中使用
[=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
[=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[x, &y] x按值传递,y按引用传递
[this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
三、lamda表达式作用
1.lamda表达式起到函数的作用。
2.代码中需要一些小函数,但是只需要一次的时候,就可以定义成lamda表达式,可以使程序更简洁。
3.通过上面的对比可以发现,C++11支持lamda表达式,并且程序写起来更加方便,并不需要定义单独的打印函数。
四、匿名函数使用例子
- 不截取任何变量
#include <iostream>
using namespace std;
int main()
{
auto testfun = [] () { cout << "hello world"; };
// testfun(); // 调用匿名函数
return 0;
}
- 直接写在main函数中,与inline函数相似。
#include<iostream>
using namespace std;
int main()
{
int x=1,y=2,z=0;
auto add = [&z](auto x,auto y){z=x+y;return z;};
auto res = add(x,y);
cout << "res:" << res << " z:" << z << endl;
}
- 与sort()函数等参数中可传入函数的方法等搭配
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
int main()
{
vector<pair<int,int>> costs; //costs的每个元素是由价值与编号组成的pair
pair<int, int> data1, data2;
data1.first = 1;
data2.first = 2;
data1.second = 1;
data2.second = 2;
costs.push_back(data1);
costs.push_back(data2);
sort(costs.begin(), costs.end(), [&](const auto & a, const auto & b)
{
if (a.first != b.first)
{
cout << "result 1" << endl;
return a.first > b.first; //价值不同时,价值大的优先
}
else
{
cout << "result 2" << endl;
return a.second < b.second; //价值相同时,标号小的优先
}
});
return 0;
}
这种方法等价于
int main()
{
vector<pair<int,int>> costs;
pair<int, int> data1, data2;
data1.first = 1;
data2.first = 2;
data1.second = 1;
data2.second = 2;
costs.push_back(data1);
costs.push_back(data2);
auto compare = [&](const auto& a,const auto& b ){
if (a.first != b.first)
{
cout << "result 1" << endl;
return a.first > b.first; //价值不同时,价值大的优先
}
else
{
cout << "result 2" << endl;
return a.second < b.second; //价值相同时,标号小的优先
}
};
sort(costs.begin(),costs.end(),compare);
return 0;
}