# 8 Expressions [expr]

## 8.1 Primary expressions [expr.prim]

### 8.1.6 Fold expressions [expr.prim.fold]

A fold expression performs a fold of a template parameter pack over a binary operator.

```fold-expression:
( cast-expression fold-operator ... )
( ... fold-operator cast-expression )
( cast-expression fold-operator ... fold-operator cast-expression )
```
```fold-operator: one of
+   -   *   /   %   ^   &   |   <<   >>
+=  -=  *=  /=  %=  ^=  &=  |=  <<=  >>=  =
==  !=  <   >   <=  >=  &&  ||  ,    .*   ->*
```

An expression of the form (... op e) where op is a fold-operator is called a unary left fold. An expression of the form (e op ...) where op is a fold-operator is called a unary right fold. Unary left folds and unary right folds are collectively called unary folds. In a unary fold, the cast-expression shall contain an unexpanded parameter pack.

An expression of the form (e1 op1 ... op2 e2) where op1 and op2 are fold-operators is called a binary fold. In a binary fold, op1 and op2 shall be the same fold-operator, and either e1 shall contain an unexpanded parameter pack or e2 shall contain an unexpanded parameter pack, but not both. If e2 contains an unexpanded parameter pack, the expression is called a binary left fold. If e1 contains an unexpanded parameter pack, the expression is called a binary right fold. [Example:

```template<typename ...Args>
bool f(Args ...args) {
return (true && ... && args); // OK
}

template<typename ...Args>
bool f(Args ...args) {
return (args + ... + args);   // error: both operands contain unexpanded parameter packs
}```

end example]