Step 1 of 9
Parameter packs and fold expressions
Some functions naturally take any number of arguments: std::make_unique<T>(args...) forwards however many the constructor needs, std::format takes a value for every {}. A variadic template accepts any number of arguments, of any types, as a parameter pack.
#include <iostream>
#include <string>
template <typename... Ts>
auto sum(Ts... xs) {
return (xs + ...); // a fold expression: x1 + (x2 + (x3 + ...))
}
template <typename... Ts>
void print_all(const Ts&... xs) {
((std::cout << xs << " "), ...); // a comma fold: do this for each x, in order
std::cout << "(" << sizeof...(xs) << " values)\n";
}
template <typename... Ts>
bool any_empty(const Ts&... strs) {
return (strs.empty() || ...); // true if at least one is empty
}
int main() {
std::cout << sum(1, 2, 3) << " " << sum(1.5, 2) << "\n";
print_all("id", 7, 2.5, 'x');
std::cout << any_empty(std::string("a"), std::string(""), std::string("c")) << "\n";
}
6 3.5
id 7 2.5 x (4 values)
1
How it works
typename... Tsdeclares a pack of types, andTs... xsa matching pack of values. Forsum(1, 2, 3),Tsisint, int, int.- A pack can't be looped over like a vector. Instead you expand it with
..., and the most useful expansion is a fold expression:(xs + ...)puts+between every element. - The pattern before the
...can be any expression using the pack:(strs.empty() || ...)callsempty()on each and joins the results with||. ((std::cout << xs << " "), ...)folds over the comma operator, which just means "do each of these, left to right". It's the loop-free way to run a statement for every element.sizeof...(xs)gives the number of elements.
Your task
For counting, turn each check into a number and add them: (int(pred(xs)) + ... + 0). The + 0 at the end makes the fold work even with zero arguments (an empty + fold with no starting value doesn't compile). all_positive is an && fold of xs > 0, which is true for an empty pack.
Your turn: write count_if_all(pred, xs...), returning how many of the arguments satisfy pred, and all_positive(xs...). Use fold expressions, no loops.