[expr.prim.fold]

# 7 Expressions [[expr]](./#expr)

## 7.5 Primary expressions [[expr.prim]](expr.prim#fold)

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

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3116)

A fold expression performs a fold of a
pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")) over a binary operator[.](#1.sentence-1)

[fold-expression:](#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]")  
( [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") ... )  
( ... [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") )  
( [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") ... [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") )

[fold-operator:](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") one of  
+  - * /  %  ^  &  |  <<  >>   
+= -= *= /= %= ^= &= |= <<= >>= =  
== != <  >  <= >= && || ,  .* ->*

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3136)

An expression of the form(... *op* e) where *op* is a [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is called a [*unary left fold*](#def:unary_left_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#2.sentence-1)

An expression of the form(e *op* ...) where *op* is a [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is called a [*unary right fold*](#def:unary_right_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#2.sentence-2)

Unary left folds and unary right folds
are collectively called [*unary folds*](#def:unary_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#2.sentence-3)

In a unary fold,
the [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") shall contain an unexpanded pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#2.sentence-4)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3152)

An expression of the form(e1 *op1* ... *op2* e2) where *op1* and *op2* are [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]")*s* is called a [*binary fold*](#def:binary_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#3.sentence-1)

In a binary fold,*op1* and *op2* shall be the same [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]"),
and either e1 shall contain an unexpanded pack
or e2 shall contain an unexpanded pack,
but not both[.](#3.sentence-2)

If e2 contains an unexpanded pack,
the expression is called a [*binary left fold*](#def:binary_left_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#3.sentence-3)

If e1 contains an unexpanded pack,
the expression is called a [*binary right fold*](#def:binary_right_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#3.sentence-4)

[*Example [1](#example-1)*: 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 packs} â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3184)

A fold expression is a pack expansion[.](#4.sentence-1)
