C++11 中的闭包
什么是闭包?
闭包是一种可以捕获其创建环境中的变量的函数。闭包允许函数在离开其创建环境后仍然访问和操作这些变量。
Lambda表达式
lambda表达式的基本语法如下:
[capture](parameters) -> return_type { // function body }; capture:指定哪些外部变量可以在lambda表达式中使用。 parameters:指定函数参数(可选)。 return_type:指定返回类型(可选,如果能从函数体推断出来,可以省略)。 function body:函数的具体实现。
捕获方式
在lambda表达式中,capture
部分指定了哪些变量以及如何捕获它们。捕获方式包括:
- 按值捕获(默认):
[x]
- 按引用捕获:
[&x]
- 捕获所有变量(按值):
[=]
- 捕获所有变量(按引用):
[&]
- 混合捕获:
[x, &y]
示例代码
下面是一些示例代码,展示了如何使用lambda表达式和闭包:
按值捕获
#include <iostream> int main()
{
int x = 10;
auto lambda = [x]()
{
return x + 1;
};
std::cout << lambda() << std::endl; // 输出 11
}
按引用捕获
#include <iostream> int main() { int x = 10;
auto lambda = [&x]() {x += 1; };
lambda();
std::cout << x << std::endl; // 输出 11
}
捕获所有变量(按值和按引用)
#include <iostream> int main() {
int x = 10;
int y = 20;
auto lambda = [=]() { return x + y; };
std::cout << lambda() << std::endl; // 输出 30
}
#include <iostream> int main() {
int x = 10; int y = 20;
auto lambda = [&]() { x += y; };
lambda();
std::cout << x << std::endl; // 输出 30
}
混合捕获
#include <iostream> int main() {
int x = 10;
int y = 20;
auto lambda = [x, &y]() { y += x; };
lambda();
std::cout << y << std::endl; // 输出 30
}
以下是一个更复杂的示例,展示了如何使用闭包在C++中进行事件处理:
#include <iostream>
#include <functional>
#include <vector>
class Event {
public:
void connect(std::function<void(int)> const& slot) {slots.push_back(slot); }
void trigger(int value) { for (auto const& slot : slots) { slot(value); }
}
private:
std::vector<std::function<void(int)>> slots;
};
int main() {
Event event;
int count = 0;
event.connect([&count](int value) {
count += value; std::cout << "Count is now " << count << std::endl; });
event.trigger(5); // 输出 "Count is now 5" event.trigger(3); // 输出 "Count is now 8" return 0;
}
在这个示例中,lambda表达式捕获了变量count
,并在事件触发时修改它。这样,可以在事件系统中方便地使用闭包来管理状态。