news 2026/10/10 9:25:08

【Effective Modern C++】第六章 lambda表达式:32. 使用初始化捕获来移动对象到闭包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Effective Modern C++】第六章 lambda表达式:32. 使用初始化捕获来移动对象到闭包

C++11 lambda 的捕获短板

我们知道 C++11 的 lambda 只有按值捕获和按引用捕获两种方式,但这两种方式都有局限,满足不了一些特殊场景:

  1. 对于只能移动、不能拷贝的对象,比如std::unique_ptr、std::future,C++11 根本没法把它们放进闭包;
  2. 对于拷贝成本很高的对象(比如大容器std::vector),我们只想移动进闭包节约开销,C++11 也做不到,只能被迫拷贝。

这是 C++11 lambda 设计上的一个明显缺陷,而 C++14 直接补上了这个短板。

C++14 的完美解决方案:初始化捕获(init capture)

C++14 引入了初始化捕获,也叫通用 lambda 捕获,它的灵活性极强,移动捕获只是它的核心用法之一,甚至能直接在捕获里创建对象,完全覆盖了 C++11 捕获的功能,还能做更多事。

1. 初始化捕获的语法逻辑
[闭包内的数据成员名 = 初始化表达式]
  • 等号左侧:是 lambda 闭包类里自定义的数据成员名称;
  • 等号右侧:是初始化这个成员的表达式,可以是移动、函数调用、临时对象等。

两者作用域不同:左侧属于闭包类,右侧是 lambda 定义的外部作用域。

2. 两种经典使用场景
  1. 把已有对象移动进闭包
auto pw = std::make_unique<Widget>(); // 将pw移动到闭包中,而非拷贝 auto func = [pw = std::move(pw)] { return pw->isValidated() && pw->isArchived(); };
  1. 直接在捕获里创建对象(连局部变量都不用)
auto func = [pw = std::make_unique<Widget>()] { return pw->isValidated() && pw->isArchived(); };

C++11 没有初始化捕获?两种模拟移动捕获的方法

如果编译器只支持 C++11,没法用初始化捕获,也能实现近似的移动捕获效果。

1. 手写仿函数类

lambda 本质就是编译器生成的闭包类,那我们可以手动写一个类,在构造函数里把对象移动到成员变量中,重载operator()实现 lambda 的逻辑,效果完全一致。

2. 用std::bind模拟(更实用、更常用)

这是 C++11 模拟移动捕获的主要思路:

  • 先把要移动的对象移动构造到std::bind生成的绑定对象里(bind 会对右值参数做移动构造);
  • 再让 lambda 以引用的方式,使用 bind 对象里存储的这个移动后的对象;
  • bind 对象的生命周期和闭包绑定,完全不用担心悬空问题。

比如移动vector进闭包的写法:

std::vector<double> data; // 填充data... auto func = std::bind( [](const std::vector<double>& data) { /* 使用闭包内的data */ }, std::move(data) // 先移动到bind对象中 );

总结

  1. C++14 环境下,直接用初始化捕获把对象移动到闭包中,简洁又安全;
  2. C++11 没有初始化捕获,就通过手写仿函数类或者std::bind的方式,模拟实现移动捕获的效果。

原著在线阅读地址

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 1:55:54

Stimulsoft Reports.JS利用拖放式设计可自定义模板

利用拖放式设计、可自定义模板和一致的品牌形象&#xff0c;为任何受众创建交互式、分析性和可打印的报告。Stimulsoft Reports.JS可视化报表设计器是一款应用程序&#xff0c;用户可以通过直观的拖放界面创建交互式、分析型且可直接打印的报表。它支持完全可自定义的模板和数据…

作者头像 李华
网站建设 2026/10/5 2:00:43

架构拆解与实战:如何用 Skill Creator 构建企业级 Agent Skills

大家好&#xff0c;我是玄姐。在 Agent 开发的深水区&#xff0c;我们不再满足于写一个好用的 Prompt&#xff0c;而是开始思考&#xff1a;如何构建一套标准化的、可复用的、具有架构美感的 Agent 技能&#xff08;Skills&#xff09;&#xff1f;今天&#xff0c;我们将深入拆…

作者头像 李华
网站建设 2026/10/10 9:25:06

建议收藏|自考必备降AIGC网站 千笔·降AIGC助手 VS 学术猹

在AI技术快速发展的今天&#xff0c;越来越多的学生和研究者开始借助AI工具辅助论文写作&#xff0c;提升效率、节省时间。然而&#xff0c;随着各大查重系统对AI生成内容的识别能力不断提升&#xff0c;"AI率超标"问题逐渐成为学术道路上的一大难题。无论是知网、维…

作者头像 李华
网站建设 2026/10/5 2:01:58

anolis23.4上命令行部署 OceanBase v4.5 版本 3节点分布式集群

看了网上&#xff0c;都是安装的v4.2或者更低版本&#xff0c;同时&#xff0c;大部分操作系统选择的是centos 7.9&#xff0c;我这里使用的是anolis23.4 &#xff0c;其他RHEL10也没有问题。另外&#xff0c;网上单节点的居多&#xff0c;我这里按生产标准安装&#xff0c;只是…

作者头像 李华
网站建设 2026/10/5 2:06:42

互联网大厂Java求职面试实战:核心技术栈与AI应用解析

互联网大厂Java求职面试实战&#xff1a;核心技术栈与AI应用解析 面试场景介绍 在一家顶级互联网大厂&#xff0c;面试官严肃而专业地与水货程序员谢飞机进行Java技术面试。面试围绕Java核心版本、构建工具、Web框架、数据库ORM、微服务云原生、安全框架、消息队列、缓存技术及…

作者头像 李华