可变参数模板是C++11引入的特性,通过参数包(typename.../Args...)和展开操作(...)支持任意数量类型与参数;核心用法包括sizeof...获取数量、递归分解处理单个参数、C++17折叠表达式简化展开,广泛用于tuple、variant等标准库组件。

可变参数模板是C++11引入的重要特性,用于编写能接受任意数量、任意类型参数的模板函数或类。核心在于参数包(parameter pack)和展开操作(...)。
基本语法:声明与展开
用typename...或class...声明类型参数包,用Args...声明形参包。展开时args...会将参数依次代入上下文。
最简示例:打印参数个数
template<typename... args>
void print_count() {
constexpr size_t n = sizeof...(Args); // 编译期获取类型数量
std::cout
void print_args_count(Args&&... args) {
constexpr size_t n = sizeof...(args); // 编译期获取实参数量
std::cout <h3>递归展开:处理每个参数</h3>
<p>由于不能直接遍历参数包,常用“头+尾”递归方式逐个处理。需提供非可变版本作为递归终止条件。</p>
<ul>
<li>定义空参数包的终止重载</li>
<li>定义至少一个参数的主模板,分离第一个参数(<code>first</code>)和剩余参数包(<code>rest...</code>)</li>
<li>在函数体内使用<code>first</code>,再递归调用自身处理<code>rest...</code>
</li>
</ul>
<pre class="brush:php;toolbar:false;">// 终止重载:空参数包
void print() {
std::cout
void print(const T& first, const Args&&... rest) {
std::cout <h3>折叠表达式(C++17):更简洁的展开方式</h3><p>替代递归,用<code>(expr ...)</code>或<code>(... expr)</code>一次性展开并组合所有参数,支持<code>+</code>、<code>&&</code>、<code>等运算符。</code></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
(std::cout :左折叠,等价于((std::cout-
(args + ...):右折叠,求和(要求所有类型支持+) -
(args && ...):逻辑与,全为true才返回true
template<typename... args>
void print_fold(Args&&... args) {
(std::cout
auto sum(Args&&... args) {
return (args + ...); // 要求所有参数可相加
}
// 使用
print_fold("a", 1, 3.14); // 输出:a13.14
std::cout <h3>在类模板中使用:存储多个类型/值</h3>
<p>可变参数模板类常用于实现元组(<code>std::tuple</code>)、类型列表或配置容器。通常结合继承或成员组合保存参数包。</p>
<p>简易类型容器示例(仅存类型信息,不存值):</p>
<pre class="brush:php;toolbar:false;">template<typename... types>
struct type_list {};
// 获取类型数量
template<typename t> struct size;
template<typename... ts>
struct size<type_list>> {
static constexpr size_t value = sizeof...(Ts);
};
static_assert(size<type_list char double>>::value == 3);
</type_list></type_list></typename...></typename></typename...>
实际应用中,std::tuple、std::variant、工厂函数、日志宏等都深度依赖可变参数模板。
基本上就这些。掌握参数包声明、sizeof...、递归分解和C++17折叠表达式,就能应对绝大多数场景。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










