- Title
- Template template parameter matching and deduction
- Status
- open
- Section
- 13.4.4 [temp.arg.template]
- Submitter
- Jason Merrill

Created on **2016-12-03.00:00:00**
last changed **50 months ago**

Date: 2016-12-03.00:00:00

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; }; //#1template<template<typename,typename> class t,typename T0,typename T1> struct match<t<T0,T1> > { typedef int type; }; //#2template<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.

History | |||
---|---|---|---|

Date | User | Action | Args |

2016-12-03 00:00:00 | admin | create |