讲师中心 微信公众号
AI工具推荐 视频效率加速

C++中的可变参数模板(Variadic Templates)是什么?(如何展开参数包)

胖芳吖_5749

胖芳吖_5749

发布时间:2026-02-13 14:18:11

|

634人浏览过

|

来源于php中文网

原创

参数包是编译期类型/值占位符,非容器亦非数组,仅可展开不可直接访问;声明为Ts...或args...,必须用...展开,支持类型包与值包共存,递归展开依赖模板重载与空包终止。

c++中的可变参数模板(variadic templates)是什么?(如何展开参数包)

什么是参数包(parameter pack)

参数包不是容器,也不是数组,它是编译期的类型/值占位符,只能被展开(unpack),不能直接访问或遍历。你写 Ts... 或 args... 的那一刻,就声明了一个参数包——它本身不占运行时内存,也不支持 size()、operator[] 这类操作。

常见错误现象:error: parameter pack 'Ts' was not expanded with '...',说明你声明了包但忘了展开;或者试图对包做 sizeof(Ts)(没加 ...),编译直接失败。

  • 参数包必须在声明处用 ... 标记,展开时也必须带 ...(位置决定展开方式)
  • 类型包(如 typename... Ts)和值包(如 Ts&&... args)可共存,但不能混用同一组 ...
  • 包展开是“全展开”或“不展开”,没有部分展开语法(比如取前两个)

如何递归展开参数包(最常用模式)

靠函数模板重载 + 递归调用是最稳妥、最易理解的方式,尤其适合需要逐个处理参数的场景(比如日志打印、构造嵌套对象)。

核心逻辑:一个重载处理“至少一个参数”的情况,另一个处理“空包”作为递归终点。

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

template<typename T, typename... Ts>
void print(T first, Ts... rest) {
    std::cout << first << " ";
    print(rest...); // 展开 rest,传给下一层
}

template<typename T>
void print(T last) {
    std::cout << last << "\n";
}

注意:第二个重载不能写成 template void print() {...},否则空参数调用会匹配失败——因为 print() 没有参数,不满足第一个模板的 T, Ts... 约束,但也不匹配单参数版本(T 无法推导)。正确收尾是只留一个非包参数的重载。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

如何用折叠表达式(C++17)一步展开

折叠表达式本质是编译器帮你自动展开成二元运算序列,适用于所有参数能统一参与同一操作的场景(求和、逻辑与、输出等),比递归更简洁、无调用开销。

两种形式:(expr op ...)(一元右折),(... op expr)(一元左折),以及带初始化的 (init op ... op expr)。

  • (std::cout 等价于 <code>std::cout
  • (args + ...) 要求所有 args 可相加,且至少一个参数;空包会编译失败
  • 若需支持空包,改用带初值的折叠:(0 + ... + args),此时空包结果为 0
  • 折叠只支持特定运算符(+, -, *, /, %, &, |, ^, &&, ||, ==, !=, , >, , 等),不支持自定义函数调用

展开时容易忽略的引用和完美转发问题

参数包里的 T&&... 不是“右值引用包”,而是“万能引用包”(universal reference),其绑定行为取决于实参。直接展开可能丢失值类别,导致意外拷贝或绑定失败。

典型陷阱:写 func(args...) 时,如果 func 是重载函数,args... 展开后每个参数都按原类型传递,但若原调用传的是临时量,而 func 只接受左值引用,就会编译失败。

  • 正确做法是用 std::forward<ts>(args)...</ts> 保持原始值类别
  • 模板参数必须是右值引用形式(typename... Ts)+ 实参用 Ts&&... 声明,才能配合 std::forward
  • 别写 std::move(args)... —— 它强制转右值,会破坏左值实参的语义
  • 如果只是传给 printf 这类 C 函数,或参数类型已知为值类型,可不转发,但务必确认无生命周期风险

参数包展开看着只是加三个点,但类型推导、引用折叠、SFINAE 交互都在背后咬着牙工作。漏掉一个 std::forward,或错放一个 ... 位置,编译器报的错往往离真相很远。

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

3140

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

269

2026.02.03

scripterror怎么解决
scripterror怎么解决

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

1029

2023.10.18

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

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

3180

2023.10.25

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

636

2023.11.23

java中void的含义
java中void的含义

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

371

2025.11.27

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

20

2026.10.28

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

40

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn