Skip to content

Commit 3f1be09

Browse files
authored
Merge 2023-11 CWG Motion 3
P2662R3 Pack Indexing
2 parents 3b1a5f7 + c831ec0 commit 3f1be09

File tree

7 files changed

+140
-15
lines changed

7 files changed

+140
-15
lines changed

source/basic.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2182,7 +2182,7 @@
21822182
followed by a \tcode{::} scope resolution operator
21832183
considers only
21842184
namespaces, types, and templates whose specializations are types.
2185-
If a name, \grammarterm{template-id}, or \grammarterm{decltype-specifier}
2185+
If a name, \grammarterm{template-id}, or \grammarterm{computed-type-specifier}
21862186
is followed by a \tcode{::},
21872187
it shall designate a namespace, class, enumeration, or dependent type,
21882188
and the \tcode{::} is never interpreted as

source/classes.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2191,7 +2191,7 @@
21912191
In an explicit destructor call, the destructor is specified by a
21922192
\tcode{\~{}}
21932193
followed by a
2194-
\grammarterm{type-name} or \grammarterm{decltype-specifier}
2194+
\grammarterm{type-name} or \grammarterm{computed-type-specifier}
21952195
that denotes the destructor's class type.
21962196
The invocation of a destructor is subject to the usual rules for member
21972197
functions\iref{class.mfct};

source/compatibility.tex

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,29 @@
3131
bool b = ne({2,3}, {1,2,3}); // unspecified result; previously \tcode{false}
3232
\end{codeblock}
3333

34+
\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: Declarations}
35+
36+
\diffref{dcl.array}
37+
\change
38+
Previously, \tcode{T...[n]} would declare a pack of function parameters.
39+
\tcode{T...[n]} is now a \grammarterm{pack-index-specifier}.
40+
\rationale
41+
Improve the handling of packs.
42+
\effect
43+
Valid \CppXXIII{} code that declares a pack of parameters
44+
without specifying a \grammarterm{declarator-id} becomes ill-formed.
45+
For example:
46+
\begin{codeblock}
47+
template <typename... T>
48+
void f(T... [1]);
49+
template <typename... T>
50+
void g(T... ptr[1]);
51+
int main() {
52+
f<int, double>(nullptr, nullptr); // ill-formed, previously \tcode{void f<int, double>(int [1], double [1])}
53+
g<int, double>(nullptr, nullptr); // ok
54+
}
55+
\end{codeblock}
56+
3457
\rSec2[diff.cpp23.library]{\ref{library}: library introduction}
3558

3659
\diffref{headers}

source/declarations.tex

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,7 @@
12861286
\nontermdef{simple-type-specifier}\br
12871287
\opt{nested-name-specifier} type-name\br
12881288
nested-name-specifier \keyword{template} simple-template-id\br
1289-
decltype-specifier\br
1289+
computed-type-specifier\br
12901290
placeholder-type-specifier\br
12911291
\opt{nested-name-specifier} template-name\br
12921292
\keyword{char}\br
@@ -1312,6 +1312,12 @@
13121312
typedef-name
13131313
\end{bnf}
13141314

1315+
\begin{bnf}
1316+
\nontermdef{computed-type-specifier}\br
1317+
decltype-specifier\br
1318+
pack-index-specifier
1319+
\end{bnf}
1320+
13151321
\pnum
13161322
\indextext{component name}
13171323
The component names of a \grammarterm{simple-type-specifier} are those of its
@@ -1383,6 +1389,7 @@
13831389
\grammarterm{type-name} & the type named \\
13841390
\grammarterm{simple-template-id} & the type as defined in~\ref{temp.names}\\
13851391
\grammarterm{decltype-specifier} & the type as defined in~\ref{dcl.type.decltype}\\
1392+
\grammarterm{pack-index-specifier} & the type as defined in~\ref{dcl.type.pack.index}\\
13861393
\grammarterm{placeholder-type-specifier}
13871394
& the type as defined in~\ref{dcl.spec.auto}\\
13881395
\grammarterm{template-name} & the type as defined in~\ref{dcl.type.class.deduct}\\
@@ -1432,6 +1439,32 @@
14321439
forces \tcode{char} objects to be signed; it is redundant in other contexts.
14331440
\end{note}
14341441

1442+
\rSec3[dcl.type.pack.index]{Pack indexing specifier}
1443+
1444+
\begin{bnf}
1445+
\nontermdef{pack-index-specifier}\br
1446+
typedef-name \terminal{...} \terminal{[} constant-expression \terminal{]}
1447+
\end{bnf}
1448+
1449+
\pnum
1450+
The \grammarterm{typedef-name} $P$ in a \grammarterm{pack-index-specifier}
1451+
shall denote a pack.
1452+
1453+
\pnum
1454+
The \grammarterm{constant-expression} shall be
1455+
a converted constant expression\iref{expr.const} of type \tcode{std::size_t}
1456+
whose value $V$, termed the index,
1457+
is such that $0 \le V < \tcode{sizeof...($P$)}$.
1458+
1459+
\pnum
1460+
A \grammarterm{pack-index-specifier} is a pack expansion\iref{temp.variadic}.
1461+
1462+
\pnum
1463+
\begin{note}
1464+
The \grammarterm{pack-index-specifier} denotes
1465+
the type of the $V^\text{th}$ element of the pack.
1466+
\end{note}
1467+
14351468
\rSec3[dcl.type.elab]{Elaborated type specifiers}%
14361469
\indextext{type specifier!elaborated}%
14371470
\indextext{\idxcode{typename}}%
@@ -1605,6 +1638,13 @@
16051638
decltype(i) x2; // type is \tcode{int}
16061639
decltype(a->x) x3; // type is \tcode{double}
16071640
decltype((a->x)) x4 = x3; // type is \tcode{const double\&}
1641+
1642+
void f() {
1643+
[](auto ...pack) {
1644+
decltype(pack...[0]) x5; // type is \tcode{int}
1645+
decltype((pack...[0])) x6; // type is \tcode{int\&}
1646+
}(0);
1647+
}
16081648
\end{codeblock}
16091649
\end{example}
16101650
\begin{note}
@@ -2367,7 +2407,6 @@
23672407
\begin{bnf}
23682408
\nontermdef{noptr-abstract-pack-declarator}\br
23692409
noptr-abstract-pack-declarator parameters-and-qualifiers\br
2370-
noptr-abstract-pack-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br
23712410
\terminal{...}
23722411
\end{bnf}
23732412

source/expressions.tex

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,8 @@
13251325
\begin{bnf}
13261326
\nontermdef{id-expression}\br
13271327
unqualified-id\br
1328-
qualified-id
1328+
qualified-id\br
1329+
pack-index-expression
13291330
\end{bnf}
13301331

13311332
\pnum
@@ -1430,7 +1431,7 @@
14301431
conversion-function-id\br
14311432
literal-operator-id\br
14321433
\terminal{\~} type-name\br
1433-
\terminal{\~} decltype-specifier\br
1434+
\terminal{\~} computed-type-specifier\br
14341435
template-id
14351436
\end{bnf}
14361437

@@ -1447,7 +1448,7 @@
14471448
\grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for
14481449
\grammarterm{literal-operator-id}{s}, see~\ref{over.literal}; for
14491450
\grammarterm{template-id}{s}, see~\ref{temp.names}.
1450-
A \grammarterm{type-name} or \grammarterm{decltype-specifier}
1451+
A \grammarterm{type-name} or \grammarterm{computed-type-specifier}
14511452
prefixed by \tcode{\~} denotes the destructor of the type so named;
14521453
see~\ref{expr.prim.id.dtor}.
14531454
Within the definition of a non-static member function, an
@@ -1595,7 +1596,7 @@
15951596
\terminal{::}\br
15961597
type-name \terminal{::}\br
15971598
namespace-name \terminal{::}\br
1598-
decltype-specifier \terminal{::}\br
1599+
computed-type-specifier \terminal{::}\br
15991600
nested-name-specifier identifier \terminal{::}\br
16001601
nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{::}
16011602
\end{bnf}
@@ -1633,8 +1634,8 @@
16331634
\pnum
16341635
The \grammarterm{nested-name-specifier} \tcode{::} nominates
16351636
the global namespace.
1636-
A \grammarterm{nested-name-specifier} with a \grammarterm{decltype-specifier}
1637-
nominates the type denoted by the \grammarterm{decltype-specifier},
1637+
A \grammarterm{nested-name-specifier} with a \grammarterm{computed-type-specifier}
1638+
nominates the type denoted by the \grammarterm{computed-type-specifier},
16381639
which shall be a class or enumeration type.
16391640
If a \grammarterm{nested-name-specifier} $N$
16401641
is declarative and
@@ -1666,9 +1667,9 @@
16661667
\pnum
16671668
A \grammarterm{qualified-id} shall not be of the form
16681669
\grammarterm{nested-name-specifier} \opt{\keyword{template}} \tcode{\~}
1669-
\grammarterm{decltype-specifier}
1670+
\grammarterm{computed-type-specifier}
16701671
nor of the form
1671-
\grammarterm{decltype-specifier} \tcode{::} \tcode{\~} \grammarterm{type-name}.
1672+
\grammarterm{computed-type-specifier} \tcode{::} \tcode{\~} \grammarterm{type-name}.
16721673

16731674
\pnum
16741675
The result of a \grammarterm{qualified-id} $Q$ is
@@ -1690,6 +1691,32 @@
16901691
\end{itemize}
16911692
and a prvalue otherwise.
16921693

1694+
\rSec3[expr.prim.pack.index]{Pack indexing expression}
1695+
1696+
\begin{bnf}
1697+
\nontermdef{pack-index-expression}\br
1698+
id-expression \terminal{...} \terminal{[} constant-expression \terminal{]}
1699+
\end{bnf}
1700+
1701+
\pnum
1702+
The \grammarterm{id-expression} $P$ in a \grammarterm{pack-index-expression}
1703+
shall be an \grammarterm{identifier} that denotes a pack.
1704+
1705+
\pnum
1706+
The \grammarterm{constant-expression} shall be
1707+
a converted constant expression\iref{expr.const} of type \tcode{std::size_t}
1708+
whose value $V$, termed the index,
1709+
is such that $0 \le V < \tcode{sizeof...($P$)}$.
1710+
1711+
\pnum
1712+
A \grammarterm{pack-index-expression} is a pack expansion\iref{temp.variadic}.
1713+
1714+
\pnum
1715+
\begin{note}
1716+
A \grammarterm{pack-index-expression} denotes
1717+
the $V^\text{th}$ element of the pack.
1718+
\end{note}
1719+
16931720
\rSec3[expr.prim.id.dtor]{Destruction}
16941721

16951722
\pnum
@@ -4696,14 +4723,14 @@
46964723
\end{note}
46974724
There is an ambiguity
46984725
in the grammar when \tcode{\~{}} is followed by
4699-
a \grammarterm{type-name} or \grammarterm{decltype-specifier}.
4726+
a \grammarterm{type-name} or \grammarterm{computed-type-specifier}.
47004727
The ambiguity is resolved by treating \tcode{\~{}} as the
47014728
operator rather than as the start of an \grammarterm{unqualified-id}
47024729
naming a destructor.
47034730
\begin{note}
47044731
Because the grammar does not permit an operator to follow the
47054732
\tcode{.}, \tcode{->}, or \tcode{::} tokens, a \tcode{\~{}} followed by
4706-
a \grammarterm{type-name} or \grammarterm{decltype-specifier} in a
4733+
a \grammarterm{type-name} or \grammarterm{computed-type-specifier} in a
47074734
member access expression or \grammarterm{qualified-id} is
47084735
unambiguously parsed as a destructor name.
47094736
\end{note}

source/preprocessor.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,7 @@
18511851
\defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep
18521852
\defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep
18531853
\defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep
1854+
\defnxname{cpp_pack_indexing} & \tcode{202311L} \\ \rowsep
18541855
\defnxname{cpp_placeholder_variables} & \tcode{202306L} \\ \rowsep
18551856
\defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep
18561857
\defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep

source/templates.tex

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,19 @@
21642164
e.g., by a \grammarterm{typedef-name}.
21652165
\end{note}
21662166

2167+
\pnum
2168+
For a type template parameter pack \tcode{T},
2169+
\tcode{T...[}\grammarterm{constant-expression}\tcode{]} denotes
2170+
a unique dependent type.
2171+
2172+
\pnum
2173+
If the \grammarterm{constant-expression} of a \grammarterm{pack-index-specifier}
2174+
is value-dependent,
2175+
two such \grammarterm{pack-index-specifier}s refer to the same type
2176+
only if their \grammarterm{constant-expression}s are equivalent\iref{temp.over.link}.
2177+
Otherwise, two such \grammarterm{pack-index-specifier}s refer to the same type
2178+
only if their indexes have the same value.
2179+
21672180
\rSec1[temp.decls]{Template declarations}
21682181

21692182
\rSec2[temp.decls.general]{General}
@@ -2763,6 +2776,12 @@
27632776
\item In a \tcode{sizeof...} expression\iref{expr.sizeof}; the pattern is an
27642777
\grammarterm{identifier}.
27652778

2779+
\item In a \grammarterm{pack-index-expression};
2780+
the pattern is an \grammarterm{identifier}.
2781+
2782+
\item In a \grammarterm{pack-index-specifier};
2783+
the pattern is a \grammarterm{typedef-name}.
2784+
27662785
\item In a \grammarterm{fold-expression}\iref{expr.prim.fold};
27672786
the pattern is the \grammarterm{cast-expression}
27682787
that contains an unexpanded pack.
@@ -2865,6 +2884,16 @@
28652884
The instantiation of a \tcode{sizeof...} expression\iref{expr.sizeof} produces
28662885
an integral constant with value $N$.
28672886

2887+
\pnum
2888+
When instantiating a \grammarterm{pack-index-expression} $P$,
2889+
let $K$ be the index of $P$.
2890+
The instantiation of $P$ is the \grammarterm{id-expression} $\tcode{E}_K$.
2891+
2892+
\pnum
2893+
When instantiating a \grammarterm{pack-index-specifier} $P$,
2894+
let $K$ be the index of $P$.
2895+
The instantiation of $P$ is the \grammarterm{typedef-name} $\tcode{E}_K$.
2896+
28682897
\pnum
28692898
The instantiation of an \grammarterm{alignment-specifier} with an ellipsis
28702899
produces $\tcode{E}_1$ $\tcode{E}_2$ $\dotsc$ $\tcode{E}_N$.
@@ -5110,7 +5139,7 @@
51105139
This includes an injected-class-name\iref{class.pre} of a class template
51115140
used without a \grammarterm{template-argument-list}.
51125141
\end{footnote}
5113-
or
5142+
\item a \grammarterm{pack-index-specifier}, or
51145143
\item denoted by \tcode{decltype(}\grammarterm{expression}{}\tcode{)},
51155144
where \grammarterm{expression} is type-dependent\iref{temp.dep.expr}.
51165145
\end{itemize}
@@ -5258,6 +5287,10 @@
52585287
\pnum
52595288
A \grammarterm{fold-expression} is type-dependent.
52605289

5290+
\pnum
5291+
A \grammarterm{pack-index-expression} is type-dependent
5292+
if its \grammarterm{id-expression} is type-dependent.
5293+
52615294
\rSec3[temp.dep.constexpr]{Value-dependent expressions}
52625295

52635296
\pnum
@@ -8197,6 +8230,8 @@
81978230
of a type that was specified using a
81988231
\grammarterm{qualified-id}.
81998232
\item
8233+
A \grammarterm{pack-index-specifier} or a \grammarterm{pack-index-expression}.
8234+
\item
82008235
The \grammarterm{expression} of a \grammarterm{decltype-specifier}.
82018236
\item
82028237
A non-type template argument or an array bound in which a subexpression

0 commit comments

Comments
 (0)