Variadic Templates

variadic template 特性本身是一个很自然的需求,它完善了 C++ 的模板设计手段原来的模板参数可以使类和函数的参数类型任意化,如果再加上参数个数的任意化,那么在参数方面的设计手段就基本上齐备了,有了variadic template 显然可以让设计出来的函数或是类有更大的复用性。因为有很多处理都是与“处理对象的个数”关系不大的,比如说打屏(printf),比如说比较大小(max,min),比如函数绑定子(bind,function要对应各种可能的函数就要能“任意”参数个数和类型)。如果不能对应任意个参数,那么就总会有人无法重用已有的实现,而不得不再重复地写一个自己需要的处理,而共通库的实现者为了尽可能地让自己写的类(函数)能复用在更多的场景,也不得不重复地写很多的代码或是用诡异的技巧,宏之类的去实现有限个“任意参数”的对应。

1. 代码示例

/*
 * Variadic Templates:可变长参数模板
 */

#include 
#include 

using namespace std;

// 边界条件
void print()
{
}

template             // typename... : 模板参数包(template parameters pack)
void print(const T& firstArg, const Types&... args) // Type... : 函数参数类型包(function parameters types pack)
{
    cout << firstArg << endl;   // print first argument
    cout << sizeof...(args) << endl; // 获取args元素个数
    print(args...);             // call print() for remaining arguents
                                // args...:函数参数包(function parameters pack)
}

int main()
{
    print(7.5, "hello", bitset<16>(377), 42);

    return 0;
}
  • ...:是一个所谓的pack(包);
  • 用于 template parameters 的为template parameters pack(模板参数包);
  • 用于 function parameters types 的为 function parameters types pack (函数参数类型包);
  • 用于 function parameters 的为function parameters pack(函数参数包);
  • 在可变长参数模板中,可用sizeof...(args)来获取参数个数

2. 可变长参数模板的选择

当泛化的模板和特化的模板并存时,编译器会选择特化的模板。如下示例:

/*
 * Variadic Templates:可变长参数模板
 */

#include 
#include 

using namespace std;

// 边界条件
void print()
{
}

template             // 特化的可变参数模板,可接受1 + n个参数
void print(const T& firstArg, const Types&... args) 
{
    cout << firstArg << endl;   
    print(args...);             
}

template       // 泛化的可变参数模板,可接受n个参数
void print(const Types&... args)
{
    cout << "the genericity" << endl;
}
int main()
{
    print(7.5, "hello", bitset<16>(377), 42);

    return 0;
}

你可能感兴趣的:(Variadic Templates)