c++11可變參數模板的使用1

1.概述

  C++11的新特性--可變模版參數(variadic templates)是C++11新增的最強大的特性之一,它對參數進行了高度泛化,它能表示0到任意個數、任意類型的參數。相比C++98/03,類模版和函數模版中只能含固定數量的模版參數,可變模版參數無疑是一個巨大的改進。然而因爲可變模版參數比較抽象,使用起來須要必定的技巧,因此它也是C++11中最難理解和掌握的特性之一。ios

  雖然掌握可變模版參數有必定難度,可是它倒是C++11中最有意思的一個特性,本文但願帶領讀者由淺入深的認識和掌握這一特性,同時也會經過一些實例來展現可變參數模版的一些用法。函數

2.可變模版參數的展開

  可變參數模板和普通模板的語義是同樣的,只是寫法上稍有區別,聲明可變參數模板時須要在typename或class後面帶上省略號「...」。好比咱們經常這樣聲明一個可變模版參數:template<typename...>或者template<class...>,一個典型的可變模版參數的定義是這樣的:spa

  template<typename... T> void fun(T... args) { }code

上面的可變模版參數的定義當中,省略號的做用有兩個:blog

1.聲明一個參數包T... args,這個參數包中能夠包含0到任意個模板參數;
2.在模板定義的右邊,能夠將參數包展開成一個一個獨立的參數。遞歸

  上面的參數args前面有省略號,因此它就是一個可變模版參數,咱們把帶省略號的參數稱爲「參數包」,它裏面包含了0到N(N>=0)個模版參數。咱們沒法直接獲取參數包args中的每一個參數的,只能經過展開參數包的方式來獲取參數包中的每一個參數,這是使用可變模版參數的一個主要特色,也是最大的難點,即如何展開可變模版參數。博客

  可變模版參數和普通的模版參數語義是一致的,因此能夠應用於函數和類,便可變模版參數函數和可變模版參數類,然而,模版函數不支持偏特化,因此可變模版參數函數和可變模版參數類展開可變模版參數的方法還不盡相同,下面咱們來分別看看他們展開可變模版參數的方法。io

 

3.可變模板參數函數

一個簡單的可變模版參數函數:模板

template<typename... T>
void fun(T... args)
{
    // 打印參數個數
    cout << sizeof...(args) << endl;  
}

 

上面的例子中,fun()沒有傳入參數,因此參數包爲空,輸出的size爲0,後面兩次調用分別傳入兩個和三個參數,故輸出的size分別爲2和3。因爲可變模版參數的類型和個數是不固定的,因此咱們能夠傳任意類型和個數的參數給函數f。這個例子只是簡單的將可變模版參數的個數打印出來,若是咱們須要將參數包中的每一個參數打印出來的話就須要經過一些方法了。展開可變模版參數函數的方法通常有兩種:一種是經過遞歸函數來展開參數包,另一種是經過逗號表達式來展開參數包。下面來看看如何用這兩種方法來展開參數包。class

3.1遞歸函數方式展開參數包

經過遞歸函數展開參數包,須要提供一個參數包展開的函數和一個遞歸終止函數,遞歸終止函數正是用來終止遞歸的,來看看下面的例子。

#include <iostream>
using namespace std;

// 最終遞歸函數
void print()
{
  cout << "empty" << endl;  
}

// 展開函數
template <typename T, typename... Args>
void print(T head, Args... args)
{
    cout << head << ",";
    print(args...);      
}

int main()
{
    print(1, 2, 3, 4);
    return 0;    
}

上例會輸出每個參數,直到爲空時輸出empty。展開參數包的函數有兩個,一個是遞歸函數,另一個是遞歸終止函數,參數包Args...在展開的過程當中遞歸調用本身,每調用一次參數包中的參數就會少一個,直到全部的參數都展開爲止,當沒有參數時,則調用非模板函數print終止遞歸過程。

遞歸調用的過程是這樣的:

print(1,2,3,4);print(2,3,4);print(3,4);print(4);print();

上面的遞歸終止函數還能夠寫成這樣:

template <class T>void print(T t){   cout << t << endl;}

修改遞歸終止函數後,上例中的調用過程是這樣的:

print(1,2,3,4);print(2,3,4);print(3,4);print(4);

當參數包展開到最後一個參數時遞歸爲止。

 

咱們將在下一博客中講解可變參數模板的其餘使用方法。

相關文章
相關標籤/搜索