Lambda表达式
-
完整结构
[capture list] (params list) mutable exception -> return type { function body }
-
有时可以省略部分结构,但中括号绝对不能省
int main() {
[] {
cout << "func()" << endl;
}; // 这就是一个lambda表达式,但运行不会打印func()因为这只是个定义,并没有调用
getchar();
return 0;
}int main() {
([] {
cout << "func()" << endl;
})(); // 这样就调用了,运行后会打印"func()"
getchar();
return 0;
}如何存储呢?
-
lambda表达式本质是个函数,应该使用一个指向函数的指针来存储它,取决于右边的函数的返回值是什么。
int main() {
void (*p)() = [] {
cout << "func()" << endl;
}; // 没有返回值所以是void,也可以用auto,反正能自动识别类型
// 调用
p();
getchar();
return 0;
}
稍微复杂一点,实现两个数的相加
// [capture list] (params list) mutable exception -> return type { function body }
auto p = [](int a, int b) -> int {
return a + b;
};
cout << p(10, 20) << endl; -
-
可以作为函数直接传入
int exec (int v1, int v2, int(*func)(int, int)) {
return func(v1, v2);
}
int main() {
cout << exec(v1, v2, [] (int v1, int v2) { return v1 + v2; }) << endl;
} -
前面的中括号 -> 变量捕获(值捕获)
int main() {
int a = 10;
int b = 20;
auto func = [] {
cout << a << endl;
cout << b << endl;
} // 直接访问a和b是不行的,应该在方括号内加入值捕获 [a, b]
// 表示外面的a和b要拷贝到lambda表达式内
auto func = [a, b] {
cout << a << endl;
cout << b << endl;
}
auto func = [=] { // 等号表示隐式捕获(值捕获)
cout << a << endl;
cout << b << endl;
}
}-
注意!值捕获和地址捕获
int main() {
int a = 10;
auto func = [a] {
cout << a << endl;
};
a = 20;
func(); // 输出为10
getchar();
return 0;
}默认捕获为值捕获,在捕获的时候a = 10,相当于直接把10传进去。
那如果想要做到捕获最新的a值怎么办?
那应该就改成地址捕获
int main() {
int a = 10;
// 地址捕获
auto func = [&a] {
cout << a << endl;
};
auto func = [&] { // &表示隐式捕获(地址捕获)
cout << a << endl;
cout << b << endl;
}
a = 20;
func(); // 输出为20
getchar();
return 0;
}
-
-
mutable
int main() {
int a = 10;
// 如果在lambda里面要改变外面变量的值,应该用地址捕获
auto func = [&a] {
a ++;
};
func();
// 用mutable
// 就算没有参数也要加小括号(格式要求)
// 并不会改变a的值,因为没有地址捕获
auto func = [a]() mutable {
// 相当于在里面又定义了一个int a = 10;
// int a =
a ++;
cout << "lambda =" << a << endl; // lambda = 11;
};
cout << a << endl; // 10;
getchar();
return 0;
}