0

0

C++中的lambda表达式捕获列表怎么用?(按值捕获与按引用捕获的区别)

冰火之心

冰火之心

发布时间:2026-01-12 13:01:02

|

617人浏览过

|

来源于php中文网

原创

按值捕获[x]复制变量,修改仅作用于副本,不影响原变量;内置类型直接赋值,类对象调用拷贝构造函数;如需修改副本须加mutable关键字。

c++中的lambda表达式捕获列表怎么用?(按值捕获与按引用捕获的区别)

按值捕获([x])会复制变量,修改不影响原变量

按值捕获在 lambda 创建时对捕获的变量做一次拷贝,后续 lambda 内部对它的任何修改都只作用于副本。适用于不需要同步更新、或原变量生命周期可能早于 lambda 的场景。

常见错误:误以为修改 [x] 中的 x 能改变外部变量,实际完全无关。

  • [x] 捕获的是 x 当前值的副本(调用 x 的拷贝构造函数)
  • 如果 x 是内置类型(如 int),就是简单赋值;如果是类对象,会调用拷贝构造函数
  • lambda 体中对 x 赋值(如 x = 42;)不会影响外部同名变量
  • 若需在 lambda 内修改捕获的副本,必须显式加 mutable 关键字,否则编译报错:error: assignment of read-only variable 'x'
int x = 10;
auto f = [x]() mutable {
    x = 99;  // ✅ 允许:修改副本
    std::cout << x << "\n";  // 输出 99
};
f();
std::cout << x << "\n";  // 输出 10:原变量未变

按引用捕获([&x])共享变量,修改直接影响原变量

按引用捕获不复制,而是保存对原变量的引用。lambda 内部对 x 的读写等价于直接操作外部变量。适用于需要实时反映变量变化,或避免拷贝开销的场景。

致命风险:若外部变量在 lambda 调用前已销毁(如局部变量出作用域),再调用 lambda 会导致未定义行为(常见 crash 或随机值)。

立即学习C++免费学习笔记(深入)”;

Google AI Studio
Google AI Studio

Google 推出的基于浏览器的集成开发环境

下载
  • [&x] 捕获的是 x 的引用,不触发拷贝或移动
  • lambda 内修改 x 就是修改原始变量,无需 mutable
  • 若捕获了局部变量的引用,而 lambda 在该局部变量生命周期结束后被调用,程序崩溃概率极高
  • 调试时常见错误信息:use of deleted valuesegmentation fault 或输出垃圾值
int x = 10;
auto f = [&x]() {
    x = 88;  // ✅ 直接改原变量
    std::cout << x << "\n";  // 输出 88
};
f();
std::cout << x << "\n";  // 输出 88

混合捕获与默认捕获([=, &y][&, x])要格外小心

混合捕获允许同时使用默认按值(=)和个别按引用(&y),或默认按引用(&)加个别按值(x)。但容易混淆哪些是引用、哪些是值,尤其当变量名相似或嵌套作用域存在同名变量时。

典型陷阱:默认按值捕获后,又用 &y 显式按引用捕获一个本可按值处理的变量,结果无意中引入悬垂引用。

  • [=, &y]:除 y 外所有变量按值捕获;y 按引用——注意 y 必须在 lambda 存活期间有效
  • [&, x]:除 x 外所有变量按引用捕获;x 按值——此时若 x 是局部变量,按值捕获安全;但其他变量全靠引用,风险集中
  • 不能同时写 [=, x][&, &y],编译器会报错:error: duplicate 'x' in capture list
  • VS 和 Clang 对混合捕获的诊断较弱,运行时出问题才暴露

捕获 this 时,[this][*this] 的本质区别

在类成员函数中,[this] 捕获的是当前对象指针的副本,lambda 内可通过 this-> 访问成员(包括非 const 成员函数);而 [*this](C++17 起支持)捕获的是当前对象的完整副本(按值),lambda 内访问的是副本的成员,与原对象彻底隔离。

这个区别常被忽略,尤其在异步回调中:用 [this] 可能导致访问已析构对象;用 [*this] 则无此风险,但无法修改原对象状态,且拷贝开销大。

  • [this]:捕获指针,轻量,但要求对象生命周期 ≥ lambda 生命周期
  • [*this]:捕获整个对象(调用拷贝构造函数),lambda 内所有成员访问都作用于副本
  • 若类含指针成员或资源句柄,[*this] 还需确保类正确实现深拷贝,否则仍可能出问题
  • 现代惯用法倾向:优先用 [weak_ptr w = shared_from_this()] 配合 lock() 安全访问,而非裸 [this]
struct Widget {
    int data = 42;
    void go() {
        auto bad = [this]() { data = 999; };           // 修改原对象
        auto good = [*this]() mutable { data = 777; }; // 修改副本,原 data 不变
    }
};
捕获列表不是语法糖,它直接决定内存布局、生命周期依赖和线程安全性。最易被忽略的是:按引用捕获的变量是否真的“活得到时候”,以及 mutable 仅解除副本的只读性,对引用捕获无效。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

187

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

271

2023.10.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

534

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

51

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

194

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.15

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

3

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.5万人学习

C 教程
C 教程

共75课时 | 4万人学习

C++教程
C++教程

共115课时 | 11.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号