Вы должны предоставить переопределения для функций для использования первых N
(обычно одного) аргументов.
void foo() {
// end condition argument pack is empty
}
template <class First, class... Rest>
void foo(First first, Rest... rest) {
// Do something with first
cout << first << endl;
foo(rest...); // Unpack the arguments for further treatment
}
Когда вы распаковываете параметр переменной, он находит следующую перегрузку.
Пример:
foo(42, true, 'a', "hello");
// Calls foo with First = int, and Rest = { bool, char, char* }
// foo(42, Rest = {true, 'a', "hello"}); // not the real syntax
Затем на следующем уровне мы расширяем предыдущий Rest
и получаем:
foo(true, Rest = { 'a', "hello"}); // First = bool
И так до тех пор, пока Rest
не содержит членов, в этом случае распаковка вызывает foo()
(перегрузка без аргументов).
Хранение упаковки, если разные типы
Если вы хотите сохранить весь пакет аргументов, вы можете использовать std::tuple
template <class... Pack>
void store_pack(Pack... p) {
std::tuple<Pack...> store( p... );
// do something with store
}
Однако это кажется менее полезным.
Хранение упаковки, если она однородна
Если все значения в пакете имеют одинаковый тип, вы можете сохранить их все так:
vector<int> reverse(int i) {
vector<int> ret;
ret.push_back(i);
return ret;
}
template <class... R>
vector<int> reverse(int i, R... r) {
vector<int> ret = reverse(r...);
ret.push_back(i);
return ret;
}
int main() {
auto v = reverse(1, 2, 3, 4);
for_each(v.cbegin(), v.cend(),
[](int i ) {
std::cout << i << std::endl;
}
);
}
Однако это кажется еще менее полезным.