0Pricing
C++ Academy · 课时

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 函数对象与仿函数
  2. Lambda 按值、按引用捕获与 mutable
  3. 泛型 Lambda 与闭包(C++14)
  4. std::function:类型擦除的可调用对象
← 返回 C++ Academy