Skip to content

Commit 84c3e66

Browse files
committed
N4295 Folding expressions
Fixed example to use the correct kind of fold.
1 parent 78b54fc commit 84c3e66

2 files changed

Lines changed: 155 additions & 3 deletions

File tree

source/expressions.tex

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@
324324
\terminal{this}\br
325325
\terminal{(} expression \terminal{)}\br
326326
id-expression\br
327-
lambda-expression
327+
lambda-expression\br
328+
fold-expression
328329
\end{bnf}
329330

330331
\begin{bnf}
@@ -1162,6 +1163,76 @@
11621163
\indextext{expression!lambda|)}%
11631164
\indextext{expression!primary|)}
11641165

1166+
\rSec2[expr.prim.fold]{Fold expressions}%
1167+
\indextext{expression!fold|(}
1168+
1169+
\pnum
1170+
A fold expression performs a fold of a template parameter
1171+
pack~(\ref{temp.variadic}) over a binary operator.
1172+
1173+
\begin{bnf}
1174+
\nontermdef{fold-expression}\br
1175+
\terminal{(} cast-expression fold-operator \terminal{...} \terminal{)}\br
1176+
\terminal{(} \terminal{...} fold-operator cast-expression \terminal{)}\br
1177+
\terminal{(} cast-expression fold-operator \terminal{...} fold-operator cast-expression \terminal{)}
1178+
\end{bnf}
1179+
1180+
\begin{bnf}
1181+
\nontermdef{fold-operator} \textnormal{one of}\br
1182+
\terminal{+ }\quad\terminal{- }\quad\terminal{* }\quad\terminal{/ }\quad\terminal{\% }\quad\terminal{\^{} }\quad\terminal{\& }\quad\terminal{| }\quad\terminal{\shl\ }\quad\terminal{\shr }\br
1183+
\terminal{+=}\quad\terminal{-=}\quad\terminal{*=}\quad\terminal{/=}\quad\terminal{\%=}\quad\terminal{\^{}=}\quad\terminal{\&=}\quad\terminal{|=}\quad\terminal{\shl=}\quad\terminal{\shr=}\quad\terminal{=}\br
1184+
\terminal{==}\quad\terminal{!=}\quad\terminal{< }\quad\terminal{> }\quad\terminal{<=}\quad\terminal{>=}\quad\terminal{\&\&}\quad\terminal{||}\quad\terminal{, }\quad\terminal{.* }\quad\terminal{->*}
1185+
\end{bnf}
1186+
1187+
\pnum
1188+
\indextext{fold!unary}%
1189+
An expression of the form
1190+
\tcode{(...} \placeholder{op} \tcode{e)}
1191+
where \placeholder{op} is a \grammarterm{fold-operator}
1192+
is called a \defn{unary left fold}.
1193+
An expression of the form
1194+
\tcode{(e} \placeholder{op} \tcode{...)}
1195+
where \placeholder{op} is a \grammarterm{fold-operator}
1196+
is called a \defn{unary right fold}.
1197+
Unary left folds and unary right folds
1198+
are collectively called \defnx{unary folds}{unary fold}.
1199+
In a unary fold,
1200+
the \grammarterm{cast-expression}
1201+
shall contain an unexpanded parameter pack~(\ref{temp.variadic}).
1202+
1203+
\pnum
1204+
\indextext{fold!binary}%
1205+
An expression of the form
1206+
\tcode{(e1} \placeholder{op1} \tcode{...} \placeholder{op2} \tcode{e2)}
1207+
where \placeholder{op1} and \placeholder{op2} are \grammarterm{fold-operator}{s}
1208+
is called a \defn{binary fold}.
1209+
In a binary fold,
1210+
\placeholder{op1} and \placeholder{op2}
1211+
shall be the same \grammarterm{fold-operator},
1212+
and either \tcode{e1}
1213+
shall contain an unexpanded parameter pack
1214+
or \tcode{e2}
1215+
shall contain an unexpanded parameter pack,
1216+
but not both.
1217+
If \tcode{e2} contains an unexpanded parameter pack,
1218+
the expression is called a \defn{binary left fold}.
1219+
If \tcode{e1} contains an unexpanded parameter pack,
1220+
the expression is called a \defn{binary right fold}.
1221+
\enterexample
1222+
\begin{codeblock}
1223+
template<typename ...Args>
1224+
bool f(Args ...args) {
1225+
return (true && ... && args); // OK
1226+
}
1227+
1228+
template<typename ...Args>
1229+
bool f(Args ...args) {
1230+
return (args + ... + args); // error: both operands contain unexpanded parameter packs
1231+
}
1232+
\end{codeblock}
1233+
\exitexample
1234+
\indextext{expression!fold|)}
1235+
11651236
\rSec1[expr.post]{Postfix expressions}%
11661237
\indextext{expression!postfix|(}
11671238

source/templates.tex

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,6 +1881,10 @@
18811881

18821882
\item In a \tcode{sizeof...} expression~(\ref{expr.sizeof}); the pattern is an
18831883
\grammarterm{identifier}.
1884+
1885+
\item In a \grammarterm{fold-expression} (\ref{expr.prim.fold});
1886+
the pattern is the \grammarterm{cast-expression}
1887+
that contains an unexpanded parameter pack.
18841888
\end{itemize}
18851889

18861890
\pnum
@@ -1940,7 +1944,8 @@
19401944

19411945
\pnum
19421946
The instantiation of a pack expansion
1943-
that is not a \tcode{sizeof...} expression
1947+
that is neither a \tcode{sizeof...} expression
1948+
nor a \grammarterm{fold-expression}
19441949
produces a
19451950
list
19461951
$\mathtt{E}_1, \mathtt{E}_2, ..., \mathtt{E}_N$,
@@ -1991,6 +1996,78 @@
19911996
an integral constant containing the number of elements in the parameter pack
19921997
it expands.
19931998

1999+
\pnum
2000+
The instantiation of a \grammarterm{fold-expression} produces:
2001+
2002+
\begin{itemize}
2003+
\item
2004+
\tcode{((}$\mathtt{E}_1$
2005+
\placeholder{op} $\mathtt{E}_2$\tcode{)}
2006+
\placeholder{op} $\cdots$\tcode{)}
2007+
\placeholder{op} $\mathtt{E}_N$
2008+
for a unary left fold,
2009+
\item
2010+
$\mathtt{E}_1$ \placeholder{op}
2011+
\tcode{(}$\cdots$ \placeholder{op}
2012+
\tcode{(}$\mathtt{E}_{N-1}$ \placeholder{op}
2013+
$\mathtt{E}_N$\tcode{))}
2014+
for a unary right fold,
2015+
\item
2016+
\tcode{(((}$\mathtt{E}$
2017+
\placeholder{op} $\mathtt{E}_1$\tcode{)}
2018+
\placeholder{op} $\mathtt{E}_2$\tcode{)}
2019+
\placeholder{op} $\cdots$\tcode{)}
2020+
\placeholder{op} $\mathtt{E}_N$
2021+
for a binary left fold, and
2022+
\item
2023+
$\mathtt{E}_1$ \placeholder{op}
2024+
\tcode{(}$\cdots$ \placeholder{op}
2025+
\tcode{(}$\mathtt{E}_{N-1}$ \placeholder{op}
2026+
\tcode{(}$\mathtt{E}_{N}$ \placeholder{op}
2027+
$\mathtt{E}$\tcode{)))}
2028+
for a binary right fold.
2029+
\end{itemize}
2030+
2031+
In each case,
2032+
\placeholder{op} is the \grammarterm{fold-operator},
2033+
$N$ is the number of elements in the pack expansion parameters,
2034+
and each $\mathtt{E}_i$ is generated by instantiating the pattern
2035+
and replacing each pack expansion parameter with its $i$th element.
2036+
For a binary fold-expression,
2037+
$\mathtt{E}$ is generated
2038+
by instantiating the \grammarterm{cast-expression}
2039+
that did not contain an unexpanded parameter pack.
2040+
\enterexample
2041+
\begin{codeblock}
2042+
template<typename ...Args>
2043+
bool all(Args ...args) { return (... && args); }
2044+
2045+
bool b = all(true, true, true, false);
2046+
\end{codeblock}
2047+
Within the instantiation of \tcode{all},
2048+
the returned expression expands to
2049+
\tcode{((true \&\& true) \&\& true) \&\& false},
2050+
which evalutes to \tcode{false}.
2051+
\exitexample
2052+
If $N$ is zero for a unary fold-expression,
2053+
the value of the expression is shown in Table~\ref{tab:fold.empty};
2054+
if the operator is not listed in Table~\ref{tab:fold.empty},
2055+
the instantiation is ill-formed.
2056+
2057+
\begin{floattable}{Value of folding empty sequences}{tab:fold.empty}
2058+
{ll}
2059+
\topline
2060+
\lhdr{Operator} & \rhdr{Value when parameter pack is empty} \\
2061+
\capsep
2062+
\tcode{*} & \tcode{1} \\
2063+
\tcode{+} & \tcode{int()} \\
2064+
\tcode{\&} & \tcode{-1} \\
2065+
\tcode{|} & \tcode{int()} \\
2066+
\tcode{\&\&} & \tcode{true} \\
2067+
\tcode{||} & \tcode{false} \\
2068+
\tcode{,} & \tcode{void()} \\
2069+
\end{floattable}
2070+
19942071
\rSec2[temp.friend]{Friends}
19952072

19962073
\pnum
@@ -4002,6 +4079,9 @@
40024079
is the type of the class member access expression.
40034080
\exitnote
40044081

4082+
\pnum
4083+
A \grammarterm{fold-expression} is type-dependent.
4084+
40054085
\rSec3[temp.dep.constexpr]{Value-dependent expressions}
40064086

40074087
\pnum
@@ -4072,7 +4152,8 @@
40724152
Expressions of the following form are value-dependent:
40734153

40744154
\begin{ncbnftab}
4075-
\terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}
4155+
\terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br
4156+
fold-expression
40764157
\end{ncbnftab}
40774158

40784159
\pnum

0 commit comments

Comments
 (0)