C++的可变参数模板(Variadic Templates)是C++11引入的一种特性,它允许我们编写可以接受任意数量、任意类型参数的模板函数或模板类。这种特性极大地增强了C++的灵活性和表达能力,特别是在处理不确定数量的参数时。
基本用法
可变参数模板的语法是通过在模板参数列表中使用省略号(...
)来表示可变数量的参数。这些参数通常被称为“参数包”(parameter pack)。
下面是一个简单的例子,展示了如何使用可变参数模板编写一个可以接受任意数量参数的函数,并将它们打印出来:
#include <iostream>
#include <string>
using namespace std;
// 定义一个可变参数模板函数
template<typename... Args>
void show_list(Args... args) {// 使用初始化列表展开参数包(std::cout << ... << args) << '\n';
}int main(void)
{int n = 14;double x = 2.71828;std::string mr = "Mr. String objects!";show_list(n, x);show_list(x * x, '!', 7, mr);return 0;
}
在这个例子中,show_list
函数是一个可变参数模板函数,它可以接受任意数量和类型的参数。在函数体内,我们使用了C++17引入的折叠表达式(fold expression)来展开参数包并打印每个参数。
递归展开参数包
在C++17之前,C++11及以后,我们需要通过递归函数或递归模板特化的方式来展开参数包。下面是一个使用递归函数展开参数包的例子:
#include <iostream>
#include <string>
using namespace std;
void show_list() {}template<typename T>
void show_list(const T& value)
{cout << value << endl;
}
template <typename T, typename... Args>
void show_list(const T& value, const Args&... args)
{cout << value << ", ";show_list(args...);
}int main(void)
{int n = 14;double x = 2.71828;std::string mr = "Mr. String objects!";show_list(n, x);show_list(x * x, '!', 7, mr);return 0;
}
在这个例子中,我们定义了两个show_list
函数:一个是无参数的递归终止函数,一个是可以处理一项的模板函数,另一个是接受至少一个参数的递归函数。递归函数首先打印第一个参数,然后递归调用自身,将剩余参数传递给下一次调用,直到参数包为空,此时调用无参数的递归终止函数。