*This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
Core Issues List revision 112e.
See http://www.open-std.org/jtc1/sc22/wg21/ for the official
list.*

2023-12-02

#### 2398.
Template template parameter matching and deduction

**Section: **13.4.4 [temp.arg.template]
**Status: **drafting
**Submitter: **Jason Merrill
**Date: **2016-12-03

Do the changes from
P0522R0
regarding template template parameter matching apply to
deduction? For example:

template<class T, class U = T> class B { /* ... */ };
template<template<class> class P, class T> void f(P<T>);
int main() {
f(B<int>()); // OK?
f(B<int,float>()); // ill-formed, T deduced to int and float
}

In deduction we can determine that `P` is more
specialized than `B`, then substitute `B`
into `P<T>`, and then
compare `B<T,T>` to `B<int,int>`.
This will allow deduction to succeed, whereas
comparing `<T>` to `<int,int>` without
this substitution would fail. I suppose this is similar to
deducing a type parameter, substituting it into the type of
a non-type parameter, then deducing the value of the
non-type parameter

Does this make sense? Do we need more wording?

Consider also this example;

template<typename> struct match;
template<template<typename> class t,typename T>
struct match<t<T> > { typedef int type; }; // #1
template<template<typename,typename> class t,typename T0,typename T1>
struct match<t<T0,T1> > { typedef int type; }; // #2
template<typename,typename = void> struct other { };
typedef match<other<void,void> >::type type;

Before this change, partial specialization #1 was not a
candidate; now it is, and neither partial specialization is
at least as specialized as the other, so we get an
ambiguity. It seems that the consistent way to address this
would be to use `other` during partial ordering, so
we'd be comparing

template<typename T>
void fn (match<other<T>>); // i.e. other<T,void>
template<typename T0, typename T1>
void fn (match<other<T0,T1>>);

So #1 is more specialized, whereas before this change we
chose #2.