A variadic template contains at least one parameter pack, so it can accept a variable number of template arguments. An ellipsis marks the pack, and another ellipsis later unpacks it. C++11 introduced variadic templates; C++17 made common unpacking easier with fold expressions. section 9.3.1 section 9.4
Read the ellipses in three common positions:
- `Ts...` expands the pack into function parameters or other expressions. section 9.3.1
Summing any number of arguments
template<typename... Ts> auto add(const Ts&... tail) { return (... + tail); } assert(6 == add(1, 2, 3)); The compiler deduces specializations such as `add<int>(int)` and `add<int, int, int>(int, int, int)`. An initializer-based fold can provide an identity value when an empty pack must be supported: `return (0 + ... + tail);`.
Counting values for a slot machine
A general-purpose `frequencies` function accepts a varying number of values, converts them to integers, expands them into an initializer list, and counts them in a map. Calls such as `frequencies(1, 3, 5)` and `frequencies(1, 3, 5, 999)` support different numbers of reels. A `std::convertible_to<int>` constraint keeps the accepted arguments suitable for tallying.
Listing 9.22 The Overload pattern
template <typename... Ts> #1
struct Overload : Ts... { #2
using Ts::operator()...; #3
};
template<typename... Ts>
Overload(Ts...) -> Overload<Ts...>; #4
The Overload pattern uses a variadic class template to inherit several lambdas and bring each `operator()` into scope, making a callable visitor for `std::variant`. section 9.3.5

