[temp.deduct.type] paragraph 8 lists all deduced contexts, but it seems not to include template-name
<TT>
where template-name
refers to a class template and TT
refers to a template template argument. Is this a deduced context?
If it is, why?
If not, consider the following code:
template<template<typename> class U, template<typename> class V>
struct foo {};
template<template<typename> class U>
struct foo<U, U> {};
int main() {}
This code compiles under Clang 7.0.0 and GCC 8.0.1, which means the compilers consider the partial specialization is more specialized than the primary template, which means U
and V
in the primary template are successfully deduced against foo<U, U>
. Is this a compiler bug?
Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.
In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
Template Parameters: These names are listed after the template keyword in a template declaration. For example, T is the single template parameter specified in our Stack example given earlier. Template Arguments: These entities are substituted for template parameters during specialization.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
This paragraph is full of problems, including the one you pointed out. Core issue 2328 has a nice list:
The presentation style of 17.9.2.5 [temp.deduct.type] paragraph 8 results in a specification that is unclear, needlessly verbose, and incomplete. Specific problems include:
What does it mean for
P
andA
to have one of a set of forms? Do they both have to have that form? (That doesn't happen; typically, onlyP
contains template parameters)In the introductory sentence, aren't
T
,TT
, andi
supposed to be the names of template parameters rather than template arguments?In
T[i]
, it appears we can deducei
, but notT
(T
can only be deduced in the formT[integer-constant]
)What is an
integer-constant
supposed to be?What is a
cv-list
?Why can we not deduce
const T
fromT
? (Apparently you only get to deduce if both or neither type have acv-list
, whatever acv-list
is.)We have extreme redundancy because, for instance, there is no way to say “in
T (T::*)(T)
, you can deduce any of thoseT
s, and it's OK if some of the positions don't have aT
”. So we have seven (!) forms of that construct, for all cases except the one where none of the three positions contain aT
.We have special case rules for pointers to member functions, even though they're not a special case and should be covered by the rule for pointers to members and the rule for functions.
We do not allow deducing a template template parameter's value from a template template argument — there is a
TT<T>
form, aTT<i>
form, atemplate-name<T>
form, and atemplate-name<i>
form, but noTT<TT>
form nortemplate-name<TT>
form.
It looks like the editor managed to get rid of cv-list
, at least, since the issue was filed. It's now just cv
. (cv-list
is kind of hilariously wrong, because [syntax] says that the -list suffix is for comma-separated lists...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With