Skip to content

Commit b43de50

Browse files
committed
P2308R1 Template parameter initialization
1 parent ecbeb5a commit b43de50

File tree

2 files changed

+120
-102
lines changed

2 files changed

+120
-102
lines changed

source/declarations.tex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4026,9 +4026,7 @@
40264026
of a function declaration
40274027
or \grammarterm{lambda-declarator}
40284028
or in a
4029-
\grammarterm{template-parameter}\iref{temp.param};
4030-
in the latter case, the \grammarterm{initializer-clause} shall be an
4031-
\grammarterm{assignment-expression}.
4029+
\grammarterm{template-parameter}\iref{temp.param}.
40324030
A default argument shall not be specified for
40334031
a template parameter pack or
40344032
a function parameter pack.
@@ -5770,6 +5768,7 @@
57705768
\item in a \tcode{return} statement\iref{stmt.return}
57715769
\item as a \grammarterm{for-range-initializer}\iref{stmt.iter}
57725770
\item as a function argument\iref{expr.call}
5771+
\item as a template argument\iref{temp.arg.nontype}
57735772
\item as a subscript\iref{expr.sub}
57745773
\item as an argument to a constructor invocation\iref{dcl.init,expr.type.conv}
57755774
\item as an initializer for a non-static data member\iref{class.mem}

source/templates.tex

Lines changed: 118 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,11 @@
411411
a non-type \grammarterm{template-parameter} of class type \tcode{T}
412412
denotes a static storage duration object of type \tcode{const T},
413413
known as a \defn{template parameter object},
414-
whose value is that of the corresponding template argument
414+
which is template-argument-equivalent\iref{temp.type} to
415+
the corresponding template argument
415416
after it has been converted
416-
to the type of the \grammarterm{template-parameter}.
417-
All such template parameters in the program of the same type
418-
with the same value denote the same template parameter object.
419-
A template parameter object shall have constant destruction\iref{expr.const}.
417+
to the type of the \grammarterm{template-parameter}\iref{temp.arg.nontype}.
418+
No two template parameter objects are template-argument-equivalent.
420419
\begin{note}
421420
If an \grammarterm{id-expression} names
422421
a non-type non-reference \grammarterm{template-parameter},
@@ -483,40 +482,27 @@
483482
for the invented type corresponding to the placeholder\iref{dcl.fct}.
484483

485484
\pnum
486-
A
487-
\defnx{default template-argument}{\idxgram{template-argument}!default}
488-
is a
489-
\grammarterm{template-argument}\iref{temp.arg} specified after
490-
\tcode{=}
491-
in a
492-
\grammarterm{template-parameter}.
493-
A default
494-
\grammarterm{template-argument}
495-
may be specified for any kind of
496-
\grammarterm{template-parameter}
497-
(type, non-type, template)
485+
A \defnadj{default}{template argument} is
486+
a template argument \iref{temp.arg} specified after \tcode{=}
487+
in a \grammarterm{template-parameter}.
488+
A default template argument may be specified for
489+
any kind of \grammarterm{template-parameter} (type, non-type, template)
498490
that is not a template parameter pack\iref{temp.variadic}.
499-
A default
500-
\grammarterm{template-argument}
501-
may be specified in a template declaration.
502-
A default
503-
\grammarterm{template-argument}
504-
shall not be specified in the
505-
\grammarterm{template-parameter-list}{s}
506-
of the definition of a member of a class template that appears outside
507-
of the member's class.
508-
A default
509-
\grammarterm{template-argument}
491+
A default template argument may be specified in a template declaration.
492+
A default template argument shall not be specified in
493+
the \grammarterm{template-parameter-list}{s}
494+
of the definition of a member of a class template
495+
that appears outside of the member's class.
496+
A default template argument
510497
shall not be specified in a friend class template declaration.
511498
If a friend function template declaration $D$
512-
specifies a default \grammarterm{template-argument},
499+
specifies a default template argument,
513500
that declaration shall be a definition and
514501
there shall be no other declaration of the function template
515502
which is reachable from $D$ or from which $D$ is reachable.
516503

517504
\pnum
518-
The set of default
519-
\grammarterm{template-argument}{s}
505+
The set of default template arguments
520506
available for use is obtained by merging the default arguments
521507
from all prior declarations of the template in the
522508
same way default function arguments are\iref{dcl.fct.default}.
@@ -532,29 +518,24 @@
532518
\end{example}
533519

534520
\pnum
535-
If a
536-
\grammarterm{template-parameter}
537-
of a class template, variable template, or alias template has a default
538-
\grammarterm{template-argument},
539-
each subsequent
540-
\grammarterm{template-parameter}
541-
shall either have a default
542-
\grammarterm{template-argument}
543-
supplied
544-
or be a template parameter pack. If a \grammarterm{template-parameter}
545-
of a primary class template, primary variable template, or alias template
546-
is a template parameter pack, it shall be the last
547-
\grammarterm{template-parameter}.
548-
A template parameter pack of a function template shall not be followed by
549-
another
550-
template parameter unless that template parameter can be deduced from the
551-
parameter-type-list\iref{dcl.fct} of the function template or has a
552-
default argument\iref{temp.deduct}.
521+
If a \grammarterm{template-parameter}
522+
of a class template, variable template, or alias template has
523+
a default template argument,
524+
each subsequent \grammarterm{template-parameter}
525+
shall either have a default template argument supplied or
526+
be a template parameter pack.
527+
If a \grammarterm{template-parameter} of
528+
a primary class template, primary variable template, or alias template
529+
is a template parameter pack,
530+
it shall be the last \grammarterm{template-parameter}.
531+
A template parameter pack of a function template
532+
shall not be followed by another template parameter
533+
unless that template parameter can be deduced from the
534+
parameter-type-list\iref{dcl.fct} of the function template or
535+
has a default argument\iref{temp.deduct}.
553536
A template parameter of a deduction guide template\iref{temp.deduct.guide}
554-
that does not have a default argument
555-
shall be deducible
556-
from the parameter-type-list
557-
of the deduction guide template.
537+
that does not have a default argument shall be deducible
538+
from the parameter-type-list of the deduction guide template.
558539
\begin{example}
559540
\begin{codeblock}
560541
template<class T1 = int, class T2> class B; // error
@@ -567,15 +548,10 @@
567548

568549
\indextext{\idxcode{<}!template and}%
569550
\pnum
570-
When parsing a
571-
default
572-
\grammarterm{template-argument}
573-
for a non-type
574-
\grammarterm{template-parameter},
575-
the first non-nested
576-
\tcode{>}
577-
is taken as the end of the
578-
\grammarterm{template-parameter-list}
551+
When parsing a default template argument
552+
for a non-type \grammarterm{template-parameter},
553+
the first non-nested \tcode{>} is taken as
554+
the end of the \grammarterm{template-parameter-list}
579555
rather than a greater-than operator.
580556
\begin{example}
581557
\begin{codeblock}
@@ -588,16 +564,12 @@
588564
\end{example}
589565

590566
\pnum
591-
A
592-
\grammarterm{template-parameter}
593-
of a template
594-
\grammarterm{template-parameter}
595-
is permitted to have a default
596-
\grammarterm{template-argument}.
597-
When such default arguments are specified, they apply to the template
598-
\grammarterm{template-parameter}
599-
in the scope of the template
600-
\grammarterm{template-parameter}.
567+
A \grammarterm{template-parameter} of
568+
a template \grammarterm{template-parameter}
569+
is permitted to have a default template argument.
570+
When such default arguments are specified,
571+
they apply to the template \grammarterm{template-parameter}
572+
in the scope of the template \grammarterm{template-parameter}.
601573
\begin{example}
602574
\begin{codeblock}
603575
template <template <class TT = float> class T> struct A {
@@ -681,7 +653,8 @@
681653
\nontermdef{template-argument}\br
682654
constant-expression\br
683655
type-id\br
684-
id-expression
656+
id-expression\br
657+
braced-init-list
685658
\end{bnf}
686659

687660
\pnum
@@ -1035,11 +1008,9 @@
10351008
X<Y::S> y; // error: \tcode{S} not accessible
10361009
\end{codeblock}
10371010
\end{example}
1038-
For a
1039-
\grammarterm{template-argument}
1040-
that is a class type or a class template, the template
1041-
definition has no special access rights to the
1042-
members of the \grammarterm{template-argument}.
1011+
For a template argument that is a class type or a class template,
1012+
the template definition has no special access rights
1013+
to the members of the template argument.
10431014
\begin{example}
10441015
\begin{codeblock}
10451016
template <template <class TT> class T> class A {
@@ -1056,11 +1027,8 @@
10561027
\end{example}
10571028

10581029
\pnum
1059-
When template argument packs or default
1060-
\grammarterm{template-argument}{s}
1061-
are used, a
1062-
\grammarterm{template-argument}
1063-
list can be empty.
1030+
When template argument packs or default template arguments are used,
1031+
a \grammarterm{template-argument} list can be empty.
10641032
In that case the empty
10651033
\tcode{<>}
10661034
brackets shall still be used as the
@@ -1093,8 +1061,7 @@
10931061
\end{example}
10941062

10951063
\pnum
1096-
If the use of a
1097-
\grammarterm{template-argument}
1064+
If the use of a template argument
10981065
gives rise to an ill-formed construct in the instantiation of a
10991066
template specialization, the program is ill-formed.
11001067

@@ -1176,23 +1143,60 @@
11761143
the type of the parameter is the type deduced
11771144
for the variable \tcode{x} in the invented declaration
11781145
\begin{codeblock}
1179-
T x = @\grammartermnc{template-argument}@ ;
1146+
T x = @$E$@ ;
11801147
\end{codeblock}
1148+
where $E$ is the template argument provided for the parameter.
1149+
\begin{note}
1150+
$E$ is a \grammarterm{template-argument} or
1151+
(for a default template argument) an \grammarterm{initializer-clause}.
1152+
\end{note}
11811153
If a deduced parameter type is not permitted
11821154
for a \grammarterm{template-parameter} declaration\iref{temp.param},
11831155
the program is ill-formed.
11841156

11851157
\pnum
1186-
A \grammarterm{template-argument}
1187-
for a non-type \grammarterm{template-parameter}
1188-
shall be a converted constant expression\iref{expr.const}
1189-
of the type of the \grammarterm{template-parameter}.
1190-
\begin{note}
1191-
If the \grammarterm{template-argument}
1192-
is an overload set
1193-
(or the address of such, including forming a pointer-to-member),
1194-
the matching function is selected from the set\iref{over.over}.
1195-
\end{note}
1158+
The value of a non-type \grammarterm{template-parameter} $P$
1159+
of (possibly deduced) type \tcode{T}
1160+
is determined from its template argument $A$ as follows.
1161+
If \tcode{T} is not a class type and
1162+
$A$ is not a \grammarterm{braced-init-list},
1163+
$A$ shall be a converted constant expression\iref{expr.const}
1164+
of type \tcode{T}; the value of $P$ is $A$ (as converted).
1165+
1166+
\pnum
1167+
Otherwise, a temporary variable
1168+
\begin{codeblock}
1169+
constexpr T v = @$A$@;
1170+
\end{codeblock}
1171+
is introduced.
1172+
The lifetime of \tcode{v} ends immediately after initializing it and
1173+
any template parameter object (see below).
1174+
For each such variable,
1175+
the \grammarterm{id-expression} \tcode{v}
1176+
is termed a \defn{candidate initializer}.
1177+
1178+
\pnum
1179+
If \tcode{T} is a class type,
1180+
a template parameter object\iref{temp.param} exists
1181+
that is constructed so as to be template-argument-equivalent to \tcode{v};
1182+
$P$ denotes that template parameter object.
1183+
$P$ is copy-initialized from an unspecified candidate initializer
1184+
that is template-argument-equivalent to \tcode{v}.
1185+
If, for the initialization from any candidate initializer,
1186+
\begin{itemize}
1187+
\item
1188+
the initialization would be ill-formed, or
1189+
\item
1190+
the full-expression of an invented \grammarterm{init-declarator}
1191+
for the initialization would not be a constant expression
1192+
when interpreted as a constant-expression\iref{expr.const}, or
1193+
\item
1194+
the initialization would cause $P$ to not be template-argument-equivalent\iref{temp.type} to \tcode{v},
1195+
\end{itemize}
1196+
the program is ill-formed.
1197+
1198+
\pnum
1199+
Otherwise, the value of $P$ is that of v.
11961200

11971201
\pnum
11981202
For a non-type \grammarterm{template-parameter} of reference or pointer type,
@@ -1236,6 +1240,21 @@
12361240
B<'a'> b2; // OK, template parameter type is \tcode{char}
12371241
B<2.5> b3; // OK, template parameter type is \tcode{double}
12381242
B<void(0)> b4; // error: template parameter type cannot be \keyword{void}
1243+
1244+
template<int i> struct C { /* ... */ };
1245+
C<{ 42 }> c1; // OK
1246+
1247+
struct J1 {
1248+
J1 *self = this;
1249+
};
1250+
B<J1{}> j1; // error: initialization of template parameter object is not a constant expression
1251+
1252+
struct J2 {
1253+
J2 *self = this;
1254+
constexpr J2() {}
1255+
constexpr J2(const J2&) {}
1256+
};
1257+
B<J2{}> j2; // error: template parameter object not template-argument-equivalent to introduced temporary
12391258
\end{codeblock}
12401259
\end{example}
12411260

@@ -2036,9 +2055,9 @@
20362055
are the same type, and
20372056

20382057
\item
2039-
their corresponding non-type \grammarterm{template-argument}{s}
2040-
are template-argument-equivalent (see below)
2041-
after conversion to the type of the \grammarterm{template-parameter}, and
2058+
the template parameter values determined by
2059+
their corresponding non-type template arguments\iref{temp.arg.nontype}
2060+
are template-argument-equivalent (see below), and
20422061

20432062
\item
20442063
their corresponding template \grammarterm{template-argument}{s}

0 commit comments

Comments
 (0)