完整的声明格式: [capture list] (params list) mutable exception-> return type { function body }
例子: [](int a, int b) -> bool { return a < b; }
捕获:
- 值捕获
1 2 3 4 5 6
int main() { int a = 123; auto f = [a] { cout << a << endl; }; a = 321; f(); // 输出:123 }
- 引用捕获
1 2 3 4 5 6
int main() { int a = 123; auto f = [&a] { cout << a << endl; }; a = 321; f(); // 输出:321 }
- 隐式值捕获
1 2 3 4 5
int main() { int a = 123; auto f = [=] { cout << a << endl; }; f(); // 输出:123 }
- 隐式引用捕获
1 2 3 4 5 6
int main() { int a = 123; auto f = [&] { cout << a << endl; }; a = 321; f(); // 输出:321 }
在 Lambda 表达式中,如果以传值方式捕获外部变量,则函数体中不能修改该外部变量,否则会引发编译错误。这时就需要使用 mutable 关键字,该关键字用以说明表达式体内的代码可以修改值捕获的变量:
1
2
3
4
5
6
int main() {
int a = 123;
auto f = [a]() mutable { cout << ++a; };
cout << a << endl; // 输出:123
f(); // 输出:124
}
参数:
- 参数列表中不能有默认参数
- 不支持可变参数
- 所有参数必须有参数名
编译产物: 不带捕获时,会多一个 retType,用于当作函数指针传递。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// auto add = [](int a, int b) -> int { return a + b; };
class __lambda_6_14 {
public:
inline int operator()(int a, int b) const { return a + b; }
using retType_6_14 = auto(*)(int, int) -> int;
inline constexpr operator retType_6_14() const noexcept {
return __invoke;
};
private:
static inline int __invoke(int a, int b) {
return __lambda_6_14{}.operator()(a, b);
}
};
带捕获(值捕获或引用捕获)时,不能当作函数指针传递,所以自然就不包含 retType。
1
2
3
4
5
6
// auto add = [&](int a, int b) -> int { return a + b; };
class __lambda_10_14 {
public:
inline int operator()(int a, int b) const { return a + b; }
};