这是我参与「第五届青训营 」伴学笔记创作活动的第4天
如果一个对象可以使用调用运算符"()", ()里面可以放参数,这个对象就是可调用对象。
常见可调用对象:
函数:
using PF = void (*)(int);
void test(int i) {
std::cout << "i:" << i << std::endl;
}
void func(PF pf, int i) {
pf(i);
}
int main(int argc, char* argv[]) {
func(test, 10);
return 0;
}
仿函数:
有operator()函数的类对象, 可以当作函数使用 ,即把()重载了
当成重载函数理解
class T {
public:
void operator()(int x) {
cout << "x:" << x << endl;
}
};
int main(int argc, char* argv[]) {
T t;
t(20); //这里类对象t可以装参数
return 0;
}
lambda表达式:
就是匿名函数,C++提供了lambda表达式,需要函数时直接在需要的地方写一个lambda表达式,省去了定义函数的过程,提高效率
C++里lambda大量使用
lambda表达式的格式:
最少是“[] {}”,完整的格式为“auto ret = [] () -> 类型{}()”
一个简单的lambda
[](int i){
std::cout<<i<<std::endl;
}(10);
完整的lambda
int pre = 10;
int a = 2;
int ret = [pre](int i) -> int {
i = i + pre;
return i;
}(a);
cout << ret << endl;
//另一种使用方式
auto ret = [pre](int i) -> int { //写auto ,不然类型太长
i = i + pre;
return i;
};
cout << ret(a) << endl;
lambda各个组件介绍
- []代表捕获列表:表示lambda表达式可以访问前文的哪些变量。
1). []表示不捕获任何变量。
2). [=]:表示按值捕获所有变量。
3). [&]:表示按引用捕获所有变量。
=,&也可以混合使用,比如
1.[=, &i]:表示变量i用引用传递,除i的所有变量用值传递。
2.[&, i]:表示变量i用值传递,除i的所有变量用引用传递。
当然,也可以捕获单独的变量
1.[i]:表示以值传递的形式捕获i
2.[&i]:表示以引用传递的方式捕获i
-
()代表lambda表达式的参数,函数有参数,lambda自然也有。
-
->ret表示指定lambda的返回值,如果不指定,lambda表达式也会推断出一个返回值的。//没有ruturn 就是void
-
{}就是函数体了,和普通函数的函数体功能完全相同。
lambda最常见用法, 给普通函数做参数:
using PF = void (*)(int); //定义一种函数指针
void func(PF pf, int x) {
pf(x);
}
int main(int argc, char* argv[]) {
int a = 2;
int b = 3;
func([](int i) {
//lambda表达式作为函数指针对象,[]必须为空
std::cout << "i:" << i << std::endl;
std::cout << "this is lambda" << std::endl;
}, a);
return 0;
}
//解决这一问题,C++11
#include<functional>
//和函数指针相同效果
using func_type = std::function<void(int)>;
void func(func_type pf, int x) {
pf(x);
}
int main(int argc, char* argv[]) {
int a = 2;
int b = 3;
func([b](int i) {
std::cout << "i:" << i << std::endl;
std::cout << "b:" << b << std::endl;
std::cout << "this is lambda" << std::endl;
}, a);
return 0;
}