-
Notifications
You must be signed in to change notification settings - Fork 781
[temp.variadic] Rearrange description of pack expansion #4543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2800,24 +2800,25 @@ | |
\end{example} | ||
|
||
\pnum | ||
The instantiation of a pack expansion | ||
that is neither a \tcode{sizeof...} expression | ||
nor a \grammarterm{fold-expression} | ||
produces a | ||
list of elements | ||
$\mathtt{E}_1,$ $\mathtt{E}_2,$ $\cdots,$ $\mathtt{E}_N$, | ||
The instantiation of a pack expansion considers | ||
items $\tcode{E}_1, \tcode{E}_2, \dotsc, \tcode{E}_N$, | ||
where | ||
$N$ is the number of elements in the pack expansion parameters. Each | ||
$\mathtt{E}_i$ is generated by instantiating the pattern and | ||
$N$ is the number of elements in the pack expansion parameters. | ||
Each $\tcode{E}_i$ is generated by instantiating the pattern and | ||
replacing each pack expansion parameter with its $i^\text{th}$ element. | ||
Such an element, in the context of the instantiation, is interpreted as | ||
follows: | ||
\begin{itemize} | ||
\item | ||
if the pack is a template parameter pack, the element is a template | ||
parameter\iref{temp.param} of the corresponding kind (type or | ||
non-type) designating the $i^\text{th}$ | ||
corresponding type or value template argument; | ||
if the pack is a template parameter pack, the element is | ||
an \grammarterm{id-expression} | ||
(for a non-type template parameter pack), | ||
a \grammarterm{typedef-name} | ||
(for a type template parameter pack declared without \tcode{template}), or | ||
a \grammarterm{template-name} | ||
(for a type template parameter pack declared with \tcode{template}) | ||
if the pack was introduced by a pack expansion, | ||
designating the $i^\text{th}$ corresponding type or value template argument; | ||
|
||
\item | ||
if the pack is a function parameter pack, the element is an | ||
|
@@ -2835,37 +2836,17 @@ | |
that resulted from instantiation of | ||
the \grammarterm{init-capture} pack. | ||
\end{itemize} | ||
|
||
All of the $\mathtt{E}_i$ become items in the enclosing list. | ||
\begin{note} | ||
The variety of list varies with the context: | ||
\grammarterm{expression-list}, | ||
\grammarterm{base-specifier-list}, | ||
\grammarterm{template-argument-list}, etc. | ||
\end{note} | ||
When $N$ is zero, the instantiation of the expansion produces an empty list. | ||
Such an instantiation does not alter the syntactic interpretation of the | ||
enclosing construct, even in cases where omitting the list entirely would | ||
When $N$ is zero, the instantiation of a pack expansion | ||
does not alter the syntactic interpretation of the enclosing construct, | ||
even in cases where omitting the pack expansion entirely would | ||
otherwise be ill-formed or would result in an ambiguity in the grammar. | ||
\begin{example} | ||
\begin{codeblock} | ||
template<class... T> struct X : T... { }; | ||
template<class... T> void f(T... values) { | ||
X<T...> x(values...); | ||
} | ||
|
||
template void f<>(); // OK: \tcode{X<>} has no base classes | ||
// \tcode{x} is a variable of type \tcode{X<>} that is value-initialized | ||
\end{codeblock} | ||
\end{example} | ||
|
||
\pnum | ||
The instantiation of a \tcode{sizeof...} expression\iref{expr.sizeof} produces | ||
an integral constant containing the number of elements in the pack | ||
it expands. | ||
an integral constant with value $N$. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we say that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p7 status quo: "A pack whose name appears within the pattern of a pack expansion is expanded by that pack expansion." What else do you want me to say? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I had interpreted that "is expanded by" as being a simple boolean property of the appearance of the pack, tying into the rule that all appearances of a pack need to be expanded, and not anything to do with substitution of the elements of the pack into some enclosing pattern. But I think it's fine to leave this as you have it. Sure, we'll substitute into the identifier and produce a bunch of id-expressions / template-names/typedef-names naming the elements of the pack, then count them and drop them on the floor, but it doesn't matter that we do so. |
||
|
||
\pnum | ||
The instantiation of a \grammarterm{fold-expression} produces: | ||
The instantiation of a \grammarterm{fold-expression}\iref{expr.prim.fold} produces: | ||
\begin{itemize} | ||
\item | ||
\tcode{((}$\mathtt{E}_1$ | ||
|
@@ -2896,11 +2877,8 @@ | |
\end{itemize} | ||
|
||
In each case, | ||
\placeholder{op} is the \grammarterm{fold-operator}, | ||
$N$ is the number of elements in the pack expansion parameters, | ||
and each $\mathtt{E}_i$ is generated by instantiating the pattern | ||
and replacing each pack expansion parameter with its $i^\text{th}$ element. | ||
For a binary fold-expression, | ||
\placeholder{op} is the \grammarterm{fold-operator}. | ||
For a binary fold, | ||
$\mathtt{E}$ is generated | ||
by instantiating the \grammarterm{cast-expression} | ||
that did not contain an unexpanded pack. | ||
|
@@ -2916,7 +2894,7 @@ | |
\tcode{((true \&\& true) \&\& true) \&\& false}, | ||
which evaluates to \tcode{false}. | ||
\end{example} | ||
If $N$ is zero for a unary fold-expression, | ||
If $N$ is zero for a unary fold, | ||
the value of the expression is shown in \tref{temp.fold.empty}; | ||
if the operator is not listed in \tref{temp.fold.empty}, | ||
the instantiation is ill-formed. | ||
|
@@ -2931,6 +2909,28 @@ | |
\tcode{,} & \tcode{void()} \\ | ||
\end{floattable} | ||
|
||
\pnum | ||
The instantiation of any other pack expansion | ||
produces a list of elements $\tcode{E}_1, \tcode{E}_2, \dotsc, \tcode{E}_N$. | ||
\begin{note} | ||
The variety of list varies with the context: | ||
\grammarterm{expression-list}, | ||
\grammarterm{base-specifier-list}, | ||
\grammarterm{template-argument-list}, etc. | ||
\end{note} | ||
When $N$ is zero, the instantiation of the expansion produces an empty list. | ||
\begin{example} | ||
\begin{codeblock} | ||
template<class... T> struct X : T... { }; | ||
template<class... T> void f(T... values) { | ||
X<T...> x(values...); | ||
} | ||
|
||
template void f<>(); // OK: \tcode{X<>} has no base classes | ||
// \tcode{x} is a variable of type \tcode{X<>} that is value-initialized | ||
\end{codeblock} | ||
\end{example} | ||
|
||
\rSec2[temp.friend]{Friends} | ||
|
||
\pnum | ||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think "if the pack was introduced by a pack expansion" should be removed for bullet 8.1. For example,
template<int...N> struct B{ B(){fun(N...);}};
, Isn't that each element instantiated inN...
does designate the corresponding template argument? However,int... N
is just a template parameter pack declaration instead of a pack expansion(where the template parameter packN
is introduced by the parameter pack declaration). If add the condition seems that the latter clause is not suitable for this case. For type template parameter pack, it is the same.template<template<class T>... TMPL> struct C{using T = U<TMPL....>;};
,template<class...T> struct D{using T = tuple<T...>;}
, in all of these cases, the pack is introduced by the parameter pack declaration that is not a pack expansion itself, but each element actually does designate the ith template argument.