-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong
Reference (section label): [temp.deduct.type]
Link to reflector thread (if any): N/A
Issue description:
https://wg21.link/temp.deduct.type#20 has
If
Phas a form that contains<i>, and if the type ofidiffers from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails.
This wording does not address what happens when the declared type of i is a placeholder type: the corresponding template argument can be read as being i (and the placeholder type deduction process would then be circular).
This wording also does not address what happens when the type of the corresponding template parameter of the template named by the enclosing simple-template-id is a placeholder type.
Suggested resolution:
If
Phas a form that contains<i>, deduction fails unless the type ofiis the same as that of the corresponding template parameterpin the specialization (fromA) of the template named by the enclosing simple-template-id; if the declared type oficontains a placeholder type, the corresponding template argument for the purposes of placeholder type deduction ([dcl.type.auto.deduct]) is an id-expression forp.
Examples:
Template parameter of the template named by the enclosing simple-template-id is auto or decltype(auto):
template<auto> struct A;
template<long long x> void f(A<x> *);
void g(A<0LL> *ap) { f(ap); } // OK, deduces `long long` value from `0LL`i is declared withauto:
template<int> struct A;
template<auto x> void f(A<x> *);
void g(A<0LL> *ap) { f(ap); } // OK, deduces `x` as an `int` value
template<int &> struct B;
template<auto x> void f(B<x> *);
int v;
void g(B<v> *bp) { f(bp); } // error: type `int` of `x` does not match the `int &` type of the template parameter in the `B<v>` specialization of `B`i is declared with decltype(auto):
template<const int &> struct A;
template<decltype(auto) x> void f(A<x> *);
int i;
void g(A<i> *ap) { f(ap); } // OK, deduces `x` as a `const int &` non-type template parameter