跳至主要內容

可变模板参数

张威大约 2 分钟c/c++模板

可变模板参数

新增的最强大的特性之一,它对参数进行了高度的泛化,它能表示****的参数。

模板参数包

template<typename… Args> class tuple;//tuple是元组的意思,其模板参数就是模板参数包

Args标识符的左侧使用了省略号,在C++11中Args被称为“模板参数包”,表示可以接受任意多个参数作为模板参数,编译器将多个模板参数打包成“单个”的模板参数包.

函数参数包

template<typename…T> void f(Targs);//args就是函数参数包

args 被称为函数参数包,表示函数可以接受多个任意类型的参数. 在C++11标准中,要求**必须唯一,且是函数的最后一个参数**; 没有当使用参数包时,省略号位于参数名称的右侧,表示立即展开该参数,这个过程也被称为解包

可变模板参数的优势

  1. 参数个数,那么对于模板来说,在模板推导的时候,就已经知道参数的个数了,也就是说在编译的时候就确定了,这样编译器就存在可能去优化代码
  2. 参数类型推导的时候也已经确定了,模板函数就可以知道参数类型了。
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;

template <typename... Args>
void print(Args... args)
{
    cout << "sizeof...(Agrs) = " << sizeof...(Args) << endl;
    cout << "sizeof...(agrs) = " << sizeof...(args) << endl;
}

void display()
{
    cout << endl;
}

template <typename T, typename... Args>
void display(T t, Args... args)
{
    cout << t << " ";
    display(args...);//当... 位于args右边的时候叫做解包
}

void test()
{
    string s1 = "hello";
    print();
    print(1, 2.2);
    print('a', true, s1);
    print(1, 2.2, 'b', "hello");
}

void test2()
{
    string s1 = "hello";
    display();
    display(1, 2.2);
    display('a', true, s1);
    display(1, 2.2, 'b', "hello");
}

template <class T>
T sum(T t)
{
    return t;
}

template <typename T, typename... Args>
T sum(T t, Args... args)
{
    return t + sum(args...);
}

void test3()
{
    cout << "sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) = "
        << sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << endl;
}

int main() {
    test();
    test2();
    test3();
    return 0;
}
$./a.out 
sizeof...(Agrs) = 0
sizeof...(agrs) = 0
sizeof...(Agrs) = 2
sizeof...(agrs) = 2
sizeof...(Agrs) = 3
sizeof...(agrs) = 3
sizeof...(Agrs) = 4
sizeof...(agrs) = 4

1 2.2 
a 1 hello 
1 2.2 b hello 
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) = 55