在下面的这个例子中,我们可以看到:

C++11之前无论是类模板还是函数模板,都只能按照其指定的样子,接受一组固定数量的模板参数。

这就涉及到了处理参数包的几种方式

不断递归地向函数传递模板参数,进而达到递归遍历所有模板参数的目的

template<typename T0>
void printf1(T0 value) {
    std::cout << value << std::endl;
}

template<typename T, typename... Ts>
void printf1(T value, Ts... args) {
    std::cout << value << std::endl;
    printf1(args...);
}

int main() {
    printf1(1, 2, "123", 1.1);
    return 0;
}

2、变参模板展开

C++17增加了变参模板展开的支持,可以在一个函数中完成printf的编写

3、初始化列表展开

template<typename T, typename... Ts>
auto printf3(T value, Ts... args) {
    std::cout << value << std::endl;
    (void) std::initializer_list<T>{
        ([&args] {
            std::cout << args << std::endl;
        }(), value)...
    };
}
int main() {
    printf3(1, 2, "123", 1.1);
    return 0;
}