cpp17 · advanced

C++17: Fold Expressions

Fold expressions (C++17) expand a parameter pack by repeatedly applying a binary operator, eliminating the recursive head/tail template and its base-case overload. There are four forms: unary right (pack op ...) groups to the right, unary left (... op pack) groups to the left, and the two binary forms (pack op ... op init) and (init op ... op pack) add an initial value so that an empty pack has a defined result — necessary because an empty unary fold is only defined for &&, ||, and the comma operator (true, false, and void() respectively) and is otherwise ill-formed. Beyond reductions like (xs + ...), the most practical use is folding over the comma operator, ((action(xs)), ...), which sequences a side effect over every element left to right — printing, push_back-ing, hashing, or visiting each argument.

🔑 Key line

C++17 fold expressions reduce/iterate a parameter pack with a binary operator and no recursion: (xs + ...) sums; ((f(xs)), ...) acts per element; use the binary form (xs op ... op init) so an empty pack has a defined result.

The code

// variadic sum WITHOUT recursion (pre-C++17 needed a base case)
template <class... Ts>
auto sum(Ts... xs) {
return (xs + ...);
} // unary right fold
template <class... Ts>
void print(const Ts&... xs) {
((std::cout << xs << ' '), ...); // fold over comma
}
template <class... Ts>
bool all_true(Ts... xs) {
return (xs && ...);
} // && fold, empty=true

What this lesson walks through

  1. 01Fold a whole pack with one operator
  2. 02Left vs right, unary vs binary
  3. 03Gotcha — empty packs need an identity
  4. 04Comma fold = do something per element

A fold collapses a parameter pack with a binary operator in a single expression — no recursive base case. (xs + ...) sums every argument.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of C++17: Fold Expressions and 100+ animated C++ interview lessons.

← Previous
C++17: Class Template Argument Deduction (CTAD)
Next →
C++17: std::any