From 5fc81f9ee2501259b8444427b758ba56a4dbfe4b Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Fri, 19 Jun 2026 17:11:25 -0700 Subject: [PATCH] P3670R4 Pack Indexing for Template Names --- source/basic.tex | 2 +- source/declarations.tex | 18 ++++++++---- source/grammar.tex | 2 +- source/preprocessor.tex | 2 +- source/templates.tex | 65 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 76 insertions(+), 13 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index c1f58de60a..f0c16df642 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -2174,7 +2174,7 @@ rules apply. In some cases a name followed by \tcode{<} is treated as a \grammarterm{template-name} -even though name lookup did not find a \grammarterm{template-name} +even though name lookup did not find the declaration of a template (see \ref{temp.names}). For example, \begin{codeblock} diff --git a/source/declarations.tex b/source/declarations.tex index 627360a226..c8ac2b003d 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1368,7 +1368,8 @@ nested-name-specifier \keyword{template} simple-template-id\br computed-type-specifier\br placeholder-type-specifier\br - \opt{nested-name-specifier} template-name\br + \opt{nested-name-specifier} simple-template-name\br + pack-index-template-name\br \keyword{char}\br \keyword{char8_t}\br \keyword{char16_t}\br @@ -1405,7 +1406,7 @@ \grammarterm{nested-name-specifier}, \grammarterm{type-name}, \grammarterm{simple-template-id}, -\grammarterm{template-name}, and/or +\grammarterm{simple-template-name}, and/or \grammarterm{type-constraint} (if it is a \grammarterm{placeholder-type-specifier}). The component name of a \grammarterm{type-name} is the first name in it. @@ -1432,19 +1433,24 @@ a type to be deduced\iref{dcl.spec.auto}. \indextext{deduction!class template arguments}% A \grammarterm{type-specifier} is a placeholder for -a deduced class type\iref{dcl.type.class.deduct} if either +a deduced class type\iref{dcl.type.class.deduct} if \begin{itemize} \item it is of the form -\opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name} or +\opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{simple-template-name}, or +\item +it is of the form +\opt{\keyword{typename}} \grammarterm{pack-index-template-name}, or \item it is of the form \opt{\keyword{typename}} \grammarterm{splice-specifier} and the \grammarterm{splice-specifier} designates a class template or alias template. \end{itemize} The \grammarterm{nested-name-specifier} or \grammarterm{splice-specifier}, -if any, shall be non-dependent and -the \grammarterm{template-name} or \grammarterm{splice-specifier} +if any, shall be non-dependent and the +\grammarterm{simple-template-name}, +\grammarterm{pack-index-template-name}, or +\grammarterm{splice-specifier} shall designate a deducible template. A \defnadj{deducible}{template} is \begin{itemize} diff --git a/source/grammar.tex b/source/grammar.tex index db27a2f510..259dabaedf 100644 --- a/source/grammar.tex +++ b/source/grammar.tex @@ -54,7 +54,7 @@ \end{ncbnf} \begin{ncbnf} -template-name:\br +simple-template-name:\br identifier \end{ncbnf} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 0bfb7f194f..d6d47072c8 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -2426,7 +2426,7 @@ \defnxname{cpp_nontype_template_args} & \tcode{201911L} \\ \rowsep \defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep \defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep -\defnxname{cpp_pack_indexing} & \tcode{202311L} \\ \rowsep +\defnxname{cpp_pack_indexing} & \tcode{202606L} \\ \rowsep \defnxname{cpp_placeholder_variables} & \tcode{202306L} \\ \rowsep \defnxname{cpp_pp_embed} & \tcode{202502L} \\ \rowsep \defnxname{cpp_range_based_for} & \tcode{202211L} \\ \rowsep diff --git a/source/templates.tex b/source/templates.tex index 369755465d..480d2e021d 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -733,6 +733,17 @@ \begin{bnf} \nontermdef{template-name}\br + simple-template-name\br + pack-index-template-name +\end{bnf} + +\begin{bnf} +\nontermdef{pack-index-template-name}\br + simple-template-name \terminal{...} \terminal{[} constant-expression \terminal{]}\br +\end{bnf} + +\begin{bnf} +\nontermdef{simple-template-name}\br identifier \end{bnf} @@ -764,10 +775,32 @@ \grammarterm{template-name} is the first name in it. +\pnum +The \grammarterm{simple-template-name} $P$ +in a \grammarterm{pack-index-template-name} +shall denote a pack. + +\pnum +The \grammarterm{constant-expression} +shall be a converted constant expression\iref{expr.const.const} +of type \tcode{std::size_t} +whose value $V$, termed the index, is such that +$0 \le V < \tcode{sizeof...(}P\tcode{)}$. + +\pnum +A \grammarterm{pack-index-template-name} +is a pack expansion\iref{temp.variadic}. + +\pnum +\begin{note} +The \grammarterm{pack-index-template-name} +denotes the $V^\text{th}$ \grammarterm{template-name} of the pack. +\end{note} + \pnum A \tcode{<} is interpreted as the delimiter of a \grammarterm{template-argument-list} -if either +if \begin{itemize} \item it follows a \grammarterm{splice-specifier} that either @@ -776,6 +809,8 @@ \item is preceded by \keyword{template} or \keyword{typename}, or \end{itemize} \item +it follows a \grammarterm{pack-index-template-name}, or +\item it follows a name that is not a \grammarterm{conversion-function-id} and \begin{itemize} \item @@ -2660,6 +2695,20 @@ Otherwise, two such \grammarterm{pack-index-specifier}s refer to the same type only if their indexes have the same value. +\pnum +Two \grammarterm{pack-index-template-name}{s} +refer to the same template only if +\begin{itemize} +\item +their \grammarterm{simple-template-name}{s} +refer to the same template parameter pack and +\item +if neither of their \grammarterm{constant-expression}{s} is value-dependent, +then they have the same value, +otherwise their \grammarterm{constant-expression}{s} +are equivalent\iref{temp.over.link}. +\end{itemize} + \rSec1[temp.decls]{Template declarations} \rSec2[temp.decls.general]{General} @@ -2906,7 +2955,7 @@ \begin{bnf} \nontermdef{deduction-guide}\br - \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \terminal{->} simple-template-id \opt{requires-clause} \terminal{;} + \opt{explicit-specifier} simple-template-name \terminal{(} parameter-declaration-clause \terminal{)} \terminal{->} simple-template-id \opt{requires-clause} \terminal{;} \end{bnf} \pnum @@ -2937,7 +2986,7 @@ a deduction guide. The \grammarterm{simple-template-id} shall name a class template specialization. -The \grammarterm{template-name} +The \grammarterm{simple-template-name} shall be the same \grammarterm{identifier} as the \grammarterm{template-name} of the \grammarterm{simple-template-id}. @@ -3300,6 +3349,9 @@ \item In a \grammarterm{pack-index-specifier}; the pattern is a \grammarterm{typedef-name}. +\item In a \grammarterm{pack-index-template-name}; +the pattern is a \grammarterm{simple-template-name}. + \item In a \grammarterm{fold-expression}\iref{expr.prim.fold}; the pattern is the \grammarterm{cast-expression} that contains an unexpanded pack. @@ -3425,6 +3477,11 @@ let $K$ be the index of $P$. The instantiation of $P$ is the \grammarterm{typedef-name} $\tcode{E}_K$. +\pnum +When instantiating a \grammarterm{pack-index-template-name} $P$, +let $K$ be the index of $P$. +The instantiation of $P$ is the \grammarterm{simple-template-name} $\tcode{E}_K$. + \pnum The instantiation of an \grammarterm{alignment-specifier} with an ellipsis produces $\tcode{E}_1$ $\tcode{E}_2$ $\dotsc$ $\tcode{E}_N$. @@ -4675,7 +4732,7 @@ \grammarterm{alias-declaration}\iref{dcl.pre} declares the \grammarterm{identifier} to be an \defnadj{alias}{template}. An alias template is a name for a family of -types. The name of the alias template is a \grammarterm{template-name}. +types. The name of the alias template is a \grammarterm{simple-template-name}. \pnum A