当前位置: 首页 > news >正文

C++ -- 可变参数模板

templatetypename F, typename... Args是 C11 引入的‌可变参数模板Variadic Templates‌声明。它是现代 C 泛型编程的基石允许函数或类接受‌任意数量‌、‌任意类型‌的参数。这行代码通常出现在实现通用工具如std::bind,std::make_shared,std::thread构造函数等的场景中。1. 语法拆解‌typename F‌:定义了一个普通的模板类型参数F。通常用来表示‌可调用对象‌的类型如函数指针、Lambda、仿函数、std::function等。‌typename... Args‌:定义了一个‌模板参数包Template Parameter Pack‌。...省略号是关键它表示Args不是一个单一类型而是一系列类型的集合例如int, double, std::string。这个包可以包含 0 个、1 个或多个类型。2. 核心用法如何“解开”参数包定义了参数包后你不能直接像使用普通类型那样使用Args。你需要通过‌包展开Pack Expansion‌来操作它。最常见的场景是配合‌完美转发Perfect Forwarding‌。典型示例实现一个简单的invoke函数#include iostream #include utility // for std::forward // 1. 声明可变参数模板 templatetypename F, typename... Args auto my_invoke(F f, Args... args) - decltype(auto) { // 2. 包展开将 args 包展开并对每个参数应用 std::forward // std::forwardArgs(args)... // 如果 Args 是 int, doubleargs 是 (a, b) // 展开后变成std::forwardint(a), std::forwarddouble(b) return std::forwardF(f)(std::forwardArgs(args)...); } void print_sum(int a, int b) { std::cout Sum: a b std::endl; } int main() { // 调用普通函数 my_invoke(print_sum, 10, 20); // 调用 Lambda my_invoke([](const std::string s) { std::cout Hello, s std::endl; }, std::string(World)); return 0; }3. 关键概念解析A. 万能引用Universal Reference / Forwarding Reference注意参数列表中的F和Args...。在模板中T并不一定代表右值引用。如果传入的是左值T会被推导为T根据引用折叠规则T 变成T左值引用。如果传入的是右值T被推导为TT保持为右值引用。‌目的‌这使得my_invoke能够接收任何类型的参数左值、右值、const、非 const并保留其原始属性。B.std::forward的作用std::forwardArgs(args)...确保参数在传递给内部函数f时保持其原始的左值/右值属性。如果没有std::forward所有参数在函数内部都会变成左值可能导致不必要的拷贝例如无法触发移动语义。C.decltype(auto)(C14)用于自动推导返回类型。它不仅能推导类型还能保留引用限定符。如果f返回一个引用my_invoke也返回引用如果返回值它也返回值。4. 常见应用场景1‌、std::thread的构造函数‌// 允许你传递任意函数和任意参数给新线程 std::thread t(my_function, arg1, arg2, arg3);2、std::make_shared/std::make_unique‌// 允许你在创建智能指针的同时直接传递构造函数的参数 auto p std::make_sharedMyClass(1, hello, 3.14);‌3、日志系统‌templatetypename... Args void log(const char* fmt, Args... args) { printf(fmt, args...); // 展开参数包传给 printf }5. 总结‌typename F‌捕获可调用对象。‌typename... Args‌捕获任意数量的参数类型。‌Args... args‌通过万能引用接收任意类型的参数值。‌std::forwardArgs(args)...‌完美转发这些参数保持其左值/右值属性避免多余拷贝。这是编写‌高性能、通用、类型安全‌的 C 库代码的标准模式。
http://www.rkmt.cn/news/1410965.html

相关文章:

  • 五分钟为Coze机器人集成论坛发帖功能:插件与API实践指南
  • 别再手动找洞了!Open Cascade 7.7.0 一键提取面内所有孔洞(内环线)的实战代码
  • 别再手动点鼠标了!用Python批量给Neo4j知识图谱上色和调整样式
  • ThinkPad X13 装 Ubuntu 16.04 双系统,我踩过的那些坑(含 grub-install 错误修复)
  • SpringBoot 消费者并发控制:线程池配置
  • 基于DGS与Apollo Router构建企业级GraphQL联邦超级图实战
  • 告别电脑依赖!用STM32F407+LCD屏做个离线二维码生成器(附完整源码)
  • Cppcheck进阶玩法:不止于基础扫描,如何用自定义规则和库文件提升检查精度?
  • 保姆级教程:用Python RDKit计算摩根分子描述符,5分钟搞定药物分子相似性分析
  • Win11太吃硬件?试试用VMware Workstation Pro 16+Ghost镜像做轻量级体验与测试
  • 告别复制粘贴:手把手教你用STM32CubeMX HAL库为8位8080 LCD屏写驱动(从引脚配置到地址计算)
  • 在openclaw中集成taotoken实现多模型智能体工作流
  • Debian 11 ‘Bullseye’ 初体验与服务器部署实战:对比CentOS迁移有哪些坑?
  • 2026年 广州消防泵最新推荐榜单:消防水泵/消防增压泵/立式消防泵/消防稳压泵/多级消防泵/XBD消防泵/消防喷淋泵/消防加压泵实力厂家精选! - 品牌企业推荐师(官方)
  • how to build gdb
  • 告别卡顿!手把手教你将TUM RGBD数据集tgz包转成30Hz流畅bag文件(附Python脚本)
  • AI增强编程实战:意图驱动开发与代码生成技术解析
  • 【踩坑实录】VMware中OpenKylin虚拟机网络失联的深度分析与排查全过程
  • 2026年5月中东专线物流公司推荐:TOP5评测专业价格适用场景 - 品牌推荐
  • 27李永乐复习全书|660题真题PDF
  • 基于LangChain与RAG技术构建智能PDF问答系统实战指南
  • AI智能体协同协议:构建高效多智能体系统的关键缺失层
  • 被吹上天的AI Agent量化,到底怎么样?
  • 从Spirent到Vector:车载以太网TC8测试方案怎么选?聊聊我们的踩坑与决策
  • 仅限首批内测团队开放:ChatGPT餐厅推荐生成工业级模板库(含21个行业定制Prompt+5类隐私脱敏策略)
  • 我用MathFlow Agent一键生成了今年电工杯A题论文 | 风光氢氨耦合系统全流程建模实录
  • 别再手动调样式了!用ArcGIS Pro的标注表达式,5分钟搞定行政区划图换行标注
  • 亦唐科技如何推动国产贴片机行业的智能化转型
  • 告别混乱!用PADS Layout高效管理你的封装库:以新建0402封装库为例
  • 2025-2026年北京定制游旅行社推荐:五大口碑产品评测深度游防行程单一市场份额价格 - 品牌推荐