Skip to content

Commit 00e313b

Browse files
committed
CWG2900 Deduction of non-type template arguments with placeholder types
1 parent 94e7e59 commit 00e313b

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
lines changed

source/declarations.tex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,11 @@
21832183
\opt{\grammarterm{type-constraint}} \keyword{auto} either with
21842184
a new invented type template parameter \tcode{U} or,
21852185
if the initialization is copy-list-initialization, with
2186-
\tcode{std::initializer_list<U>}. Deduce a value for \tcode{U} using the rules
2186+
\tcode{std::initializer_list<U>}.
2187+
If $E$ is a value synthesized for a constant template parameter
2188+
of type \tcode{decltype(auto)}\iref{temp.func.order},
2189+
the declaration is ill-formed.
2190+
Otherwise, deduce a value for \tcode{U} using the rules
21872191
of template argument deduction from a function call\iref{temp.deduct.call},
21882192
where \tcode{P} is a
21892193
function template parameter type and

source/templates.tex

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4372,11 +4372,9 @@
43724372
variable template, or concept,
43734373
respectively, and substitute it for each occurrence of that parameter
43744374
in the function type of the template.
4375-
\begin{note}
4376-
The type replacing the placeholder
4375+
The type replacing a placeholder
43774376
in the type of the value synthesized for a constant template parameter
4378-
is also a unique synthesized type.
4379-
\end{note}
4377+
is a unique synthesized type.
43804378

43814379
\pnum
43824380
%FIXME: What's a "synthesized template"? Do we mean the synthesized
@@ -9390,11 +9388,16 @@
93909388
\end{note}
93919389

93929390
\pnum
9393-
If \tcode{P} has a form that contains \tcode{<i>}, and
9394-
if the type of \tcode{i} differs from the type
9391+
If \tcode{P} has a form that contains \tcode{<i>},
9392+
deduction fails unless the type of \tcode{i} is the same as that
93959393
of the corresponding template parameter
9394+
\tcode{p} in the specialization (from \tcode{A})
93969395
of the template named by the enclosing \grammarterm{simple-template-id} or
9397-
\grammarterm{splice-specialization-specifier}, deduction fails.
9396+
\grammarterm{splice-specialization-specifier};
9397+
if the declared type of \tcode{i} contains a placeholder type,
9398+
the corresponding template argument for the purposes of
9399+
placeholder type deduction\iref{dcl.type.auto.deduct}
9400+
is an \grammarterm{id-expression} for \tcode{p}.
93989401
If \tcode{P} has a form that contains \tcode{[i]}, and if the type of
93999402
\tcode{i} is not an integral type, deduction fails.
94009403
\begin{footnote}
@@ -9414,15 +9417,54 @@
94149417
template<short s> void f(A<s>);
94159418
void k1() {
94169419
A<1> a;
9417-
f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short}
9418-
f<1>(a); // OK
9420+
f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short}
9421+
f<1>(a); // OK
94199422
}
94209423

94219424
template<const short cs> class B { };
94229425
template<short s> void g(B<s>);
94239426
void k2() {
94249427
B<1> b;
9425-
g(b); // OK, cv-qualifiers are ignored on template parameter types
9428+
g(b); // OK, cv-qualifiers are ignored on template parameter types
9429+
}
9430+
9431+
template<auto> struct C;
9432+
template<long long x> void f(C<x> *);
9433+
void g(C<0LL> *ap) {
9434+
f(ap); // OK, deduces long long value from 0LL
9435+
}
9436+
9437+
template<int> struct D;
9438+
template<auto x> void f(D<x> *);
9439+
void g(D<0LL> *ap) {
9440+
f(ap); // OK, deduces x as an int value
9441+
}
9442+
9443+
template<int &> struct E;
9444+
template<auto x> void f(E<x> *);
9445+
int v;
9446+
void g(E<v> *bp) {
9447+
f(bp); // error: type \tcode{int} of \tcode{x} does not match the \tcode{int &} type
9448+
} // of the template parameter in the \tcode{E<v>} specialization of \tcode{E}
9449+
9450+
template<const int &> struct F;
9451+
template<decltype(auto) x> void f(F<x> *);
9452+
int i;
9453+
void g(F<i> *ap) {
9454+
f(ap); // OK, deduces \tcode{x} as a constant template parameter of type \tcode{const int &}
9455+
}
9456+
9457+
template <decltype(auto) q> struct G;
9458+
template <auto x> long *f(G<x> *); // \#1
9459+
template <decltype(auto) x> short *f(G<x> *); // \#2
9460+
9461+
const int j = 0;
9462+
short *g(G<(j)> *ap) { // OK, \tcode{q} has type \tcode{const int &}
9463+
return f(ap); // OK, only \tcode{#2} matches
9464+
}
9465+
9466+
long *g(G<j> *ap) { // OK, \tcode{q} has type \tcode{int}
9467+
return f(ap); // OK, \#1 is more specialized
94269468
}
94279469
\end{codeblock}
94289470
\end{example}

0 commit comments

Comments
 (0)