一、变参模板的定义
变参模板的意思说的是从 C++ 11 开始,模板参数接受不变的个数。类似于 C 语言中的 printf() 函数一样。
二、变参模板的定义及使用
定义一个变参模板,其中 print() 为重载的函数,第一个是普通的函数,第二个变参模板函数。
void print() {
std::cout << "print over" << std::endl;
}
template<typename T, typename...Types>
void print(T firstArgs, Types...args) {
std::cout << firstArgs << std::endl;
std::cout << "types: " << sizeof...(Types) << std::endl;
std::cout << "args: " << sizeof...(args) << std::endl;
print(args...);
}
然后,调用如下
print(7.5, "Hello", "World");
我们可以传入任意类型及个数的参数,前面会一直递归调用变参模板函数,然后在没有参数后,调用 print() 退出递归。
上面注意,定义变参 type 时,如下在 typename 后面加...
typename... Types
声明参数时,在 Types 后面加...
Types... args
而使用参数时,在 args 后面...
args...
也就是说都是在关键字、类型、参数后面加 ...
三、变参模板的其他主题
1. 新的运算符, sizeof...()
sizeof...() 既可以计算 Types 的个数,也可以计算 args 的个数,如上 demo 中。
2. 折叠表达式
从 c++17 开始提供了一个二元运算符,可以在直接计算出变参参数的结果。
template<typename...Types>
auto foldSum(Types... t) {
return (... + t);
}
折叠表达式的几种形式如下
3. 变参模板在实际中的使用
智能指针 std::make_shared 如 std::make_shared<T>(1,2,3,4....)
std::vector 的 emplace() ,如 emplace(1,2,3,4,"hello")
std::thread 线程函数的参数 ,如 std::thread(func, 1, 2, "hello");
其他更多主题待参考。