在c++中我們需要同種函式擁有不同種的功能時,首先想到的函式過載,但是過載種模擬較多時我們會使用模板函式(或者是模板函式過載以及模板函式的具體化)來幫助我們更加泛化,但這些方法的特點是函式引數的個數是確定的,假如我們需要引數個數是可以動態變化的話,上面的幾個方法就不夠用了。這時我們就可以使用variadic template以及initializer_list來解決這個問題。
用print函式來演示上述兩種方法
void
print()
template ,typename ... types>
void
print
(t first ,types ... rest)
簡單分析一下,上面使用了這個…這個非常關鍵的東西pack,這個包的概念是比較重要的。可以這樣理解,…在模板引數列表中放在typename的後面,代表有…個typename,然後把這…稱為template parameter packs(模板引數包),並起名為types。
函式中的…被稱為function parameter types pack(函式引數型別包),這個pack可以給個名字rest。
進入函式列印完first之後進入遞迴,這時我們傳的引數是剛才的pack,這個pack再分解為乙個型別加乙個包,依此類推,直到後面分解為乙個型別加0個包,這也就是我們為什麼要定義乙個無引數的空的print函式。
假如需要了解到我們傳進去的引數個數有多少個,我們可以用sizeof運算子
sizeof...
(rest)+1
;
注意這個…的位置,放錯位置會報莫名其妙的錯誤。測試程式可以是
int main()
然後他就能列印出所有的引數了。
第二種是initializer_list,這時乙個類模板,所以我們使用的時候需要為它指定型別,當然,這個型別也可以是模板。例項如下。
//initialize_list 迭代版本的print
#include
#include
template>
void
print
(initializer_list<
t> inilist)
}
這個用法本身比較簡單,不過從**我們也可以看出它可以任意個數,但不能任意型別,必須是同種型別。而且型別必須嚴格一致或者是可以進行型別轉換的(所以你得清楚什麼樣的型別轉換是允許或者說是安全的),函式的書寫方式也有細節需要注意,放**吧
//注意呼叫方式,須將引數用大括號括起來
int main()
);//執行通過
print()
;//執行也通過,因為可以呼叫string 的建構函式把字串轉化為string型別
print()
//error,型別不匹配
print()
;//通過
print()
;//通過
print()
;//通過
//另外一種初始化方式
initializer_list mystring =
;//時刻注意這是乙個類,所以也是可以建立物件的,這樣就可以用我們習慣的方式呼叫print函式了。
print
(mystring)
;//通過
cin.
get();
}
**雖然看起來多,但是關鍵就是知道怎麼樣得型別才是允許的,安全的。
然後我們可以用這個方式做一些更好的事情,比如比較大小。
常用的比較大小是兩個兩個比較的,但是用這個就可以一次性比較多個。stl庫裡面的min函式的引數就是這個類。我們可以試著簡單實現一下。
template>
tminfun
(initializer_list<
t> inilist)
return
*found;
}int main()
; int a =
minfun
(ini)
; cout << a << endl;
cin.
get();
}
執行過後是符合我們的基本功能的。 C中可變引數函式
先說明規則 1.函式的可變引數中必須有一條確定的引數 至少一條 2.可變引數列表必須從頭開始訪問,訪問到尾部 3.可變引數列變不能確定引數數目 編譯時才能確定 4.可變引數的變數型別是不確定的,編譯時必須確定引數型別,變數的引數型別不確定時,函式的結果未知。引數使用方法 include va lis...
函式中的可變引數c
在資料的大小,個數,型別是未知的情況下,會用到可變引數。include include include 標準引數,解決可變引數問題 intadd int num,va end argp 結束讀取 return res void main include include include 標準引數,解決...
C 中函式中的可變引數
using system using system.collections.generic using system.linq using system.text vfun values console.writeline vfun aaa bbb ccc console.writeline say...