Variadic Templates

weixin_33890499發表於2018-06-29

variadic template 特性本身是一個很自然的需求,它完善了 C++ 的模板設計手段原來的模板引數可以使類和函式的引數型別任意化,如果再加上引數個數的任意化,那麼在引數方面的設計手段就基本上齊備了,有了variadic template 顯然可以讓設計出來的函式或是類有更大的複用性。因為有很多處理都是與“處理物件的個數”關係不大的,比如說打屏(printf),比如說比較大小(max,min),比如函式繫結子(bind,function要對應各種可能的函式就要能“任意”引數個數和型別)。如果不能對應任意個引數,那麼就總會有人無法重用已有的實現,而不得不再重複地寫一個自己需要的處理,而共通庫的實現者為了儘可能地讓自己寫的類(函式)能複用在更多的場景,也不得不重複地寫很多的程式碼或是用詭異的技巧,巨集之類的去實現有限個“任意引數”的對應。

1. 程式碼示例

/*
 * Variadic Templates:可變長引數模板
 */

#include <iostream>
#include <bitset>

using namespace std;

// 邊界條件
void print()
{
}

template <typename T, typename... Types>            // 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 <iostream>
#include <bitset>

using namespace std;

// 邊界條件
void print()
{
}

template <typename T, typename... Types>            // 特化的可變引數模板,可接受1 + n個引數
void print(const T& firstArg, const Types&... args) 
{
    cout << firstArg << endl;   
    print(args...);             
}

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

    return 0;
}

相關文章