用可變參數模板編寫函數是很簡單的,它接受任意數量的參數。與一般模式唯一的區別在於,具體類型被用作第一個參數(頭部) - 而不是模板參數。以下示例顯示了一個函數foobar
,它接受任意數量的字符串。
// used for end of recursion - and for the empty arguments list
void foobar() { }
template <typename ...Tail>
void foobar(const std::string& head, Tail&&... tail)
{
// do something with head
std::cout << head << '\n';
// call foobar recursively with remaining arguments
foobar(std::forward<Tail>(tail)...);
}
foobar("Hello", "World", "...");
個人而言,我更喜歡使用std::initializer_list
而不是可變參數模板。由於可變模板更復雜,需要額外的經驗。使用std::initializer_list
與普通函數時
void foobar(std::initializer_list<std::string> values)
{
for (auto& value : values) {
// do something with value
std::cout << value << '\n';
}
}
foobar({ "Hello", "World", "...", });
不幸的是,需要額外花括號:隨着std::initializer_list
,它可能是這樣的。如果使用新的初始化程序語法,則它們不是構造函數所必需的。
編輯:根據反饋重寫了答案。特別是我改變了兩個解決方案/例子的順序。
我認爲這全是關於我的誤解。我知道第二種方式,但我一直認爲參數類型無法控制。這不是真的。因爲該函數接受一個已知類型的第一個參數(字符串在這裏),所以它被隱含地強制擁有該類型的參數。謝謝。 – melmi 2012-04-06 16:39:00
您可能需要先移動第二個代碼框。這是一個非常好的解決方案,而'initializer_list'版本不是。我打算用SFINAE等發佈一個大型複雜的東西,但這更合理。 – 2012-04-06 16:43:29
@nosid通過在std :: initializer_list版本週圍創建一個可變模板包裝器,你可以避免使用大括號,如果你混合使用std :: initializer_list和variadic模板方法,就像這樣:[see coliru](http: //coliru.stacked-crooked.com/a/4baef67192a0310c)。 – 2016-05-31 02:37:32