变参模板1:入门
题目描述
变参模板是指模板参数不定长的模板。它是 C++ 元编程的重要组成部分,也是许多现代 C++ 标准库设施的构成成分。
在模板形参列表中,可以用 typename... Ts
引入模板形参包 Ts
。也就是说,给普通的模板形参的声明前,加上 ...
,就可以让这个形参变成“形参包”。“形参包”顾名思义就是任意多个模板形参的集合。
template <typename... Ts>
struct S {};
S<> s1; // OK
S<int> s2; // OK
S<int, bool> s3; // OK
S<char, bool, double, long, unsigned> s4; // OK
像这样,模板 S
通过引入形参包 Ts
,就能接收任意多个模板实参。
那如何使用模板形参包呢?我们先通过函数形参包这种用法来使用。对于函数变参模板,可以将最后一个函数形参声明为如下形式:
template <typename... Ts>
void f(int a, Ts... args);
这里的 args
就是函数形参包,写成“模板形参包名 + ...
+ 形参名”。它的含义是:对于模板形参包中的每一个类型,都引入一个形参到函数声明。由于模板形参包的类型个数是任意的,从而这个函数模板 f
也可以接受任意多个实参。(注意第一个参数不是变参,它固定地声明为 int
;剩余的部分是可变的。此外,函数形参包只能出现一次,而且是形参列表的结尾。)
f(0); // 调用 f<>
f(0, 42); // 调用 f<int>
f(0, '@', false, 3.14, 42L); // 调用 f<char, bool, double, long>
进一步,如何使用函数形参包呢?目前我们可以先了解一下 sizeof...
运算符,它返回形参包中的类型/形参个数。比如 sizeof...(args)
在上面三个例子中,分别得到 0、1 和 4。
下面请补充代码,实现 count
函数模板;它输出传入了多少个实参。
关于输入
无
关于输出
见样例输出
参考答案
#include <iostream>
template <typename... Args>
void count(const Args&... args) {
std::cout << sizeof...(args) << std::endl;
}
int main() {
count();
count(false);
count("hello", "world");
count("do not", "dereference", nullptr);
count(1, '+', 1LL, "=", 2.0);
}