Lambda 按值、按引用捕获与 mutable
审慎选择捕获子句,并理解 Lambda 的状态
Lambda 按值、按引用捕获与 mutable 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
捕获总结
Lambda 表达式的捕获子句列出它可以使用的外围作用域中的变量。捕获模式决定了每个变量的访问方式。
按值捕获
未使用 & 列出的名称会在 Lambda 表达式创建时被复制。Lambda 表达式持有自己的副本。
int n = 5;
auto f = [n]() { return n * 2; };
n = 10;
std::cout << f(); // 10 (captured n was 5)按引用捕获
带有 & 的名称会以引用形式存储,指向外部变量。两边的更改都会相互传递。
int counter = 0;
auto inc = [&counter]() { ++counter; };
inc(); inc();
std::cout << counter; // 2默认捕获:=
[=] 会按值捕获 Lambda 表达式主体中使用的所有内容。这种方式很方便,但也可能令人意外——它只捕获被引用的变量。
int a = 1, b = 2, c = 3;
auto f = [=]() { return a + c; }; // captures a and c (not b)默认捕获:&
[&] 会按引用捕获所有被使用的内容。请注意:如果 Lambda 表达式的生命周期超过了作用域,对局部变量的引用就会悬空。
int n = 0;
auto bad = [&]() { return n; };
return bad; // n dies, lambda dangles混合捕获模式
您可以组合默认捕获和指定捕获。列出单个变量即可覆盖默认设置。
int a = 1, b = 2;
auto f = [=, &b]() { // a by value, b by reference
return a + b;
};可变 Lambda 表达式
按值捕获的变量在 Lambda 表达式内部是 const。添加 mutable 可让 Lambda 表达式修改所捕获的副本。
int n = 5;
auto inc = [n]() mutable {
++n;
return n;
};
inc(); inc();
std::cout << n; // 5 (outer unchanged)初始化捕获(C++14)
您可以使用新名称捕获表达式的结果。这支持通过移动进行捕获以及使用计算得到的初始值。
auto ptr = std::make_unique<int>(42);
auto f = [p = std::move(ptr)]() {
return *p;
};
// ptr is now empty; p owns the int inside the lambda捕获 this
在成员函数内部,[this] 会捕获 this 指针,因此可以在 Lambda 表达式内部访问所有成员。
捕获 *this(C++17)
[*this] 会将整个对象复制到 Lambda 表达式中。当 Lambda 表达式的生命周期超过原始对象时,这种方式很有用。
注意事项:按引用捕获与异步执行
绝不要将局部变量按引用捕获到异步运行的 Lambda 表达式中——局部变量很可能会在 Lambda 表达式执行前就被销毁。
// BUG
int local = 42;
std::async([&local]() { use(local); }); // local dies, lambda dangles快速检查
如果要让 Lambda 表达式持有外围作用域中 std::unique_ptr 的所有权,应该使用哪种捕获模式?
总结
按值捕获会复制变量,按引用捕获会建立别名。请谨慎使用默认捕获 [=] 或 [&]。mutable 允许修改按值捕获的副本。初始化捕获(C++14)支持通过移动进行捕获。
常见问题解答
「Lambda 按值、按引用捕获与 mutable」课时是免费的吗?
是的 — 「Lambda 按值、按引用捕获与 mutable」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「Lambda 按值、按引用捕获与 mutable」这节课中我会学到什么?
审慎选择捕获子句,并理解 Lambda 的状态 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「Lambda 按值、按引用捕获与 mutable」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 函数对象与仿函数
- Lambda 按值、按引用捕获与 mutable
- 泛型 Lambda 与闭包(C++14)
- std::function:类型擦除的可调用对象