[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?
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...)
It's correct, template-name<TT>
is not a deduced context. That's not relevant here. Plain TT
is a deduced context, and that's what you have here
The deduced context template-name<I>
for a non-type template parameter I
means that you can deduce 5
when you have argument Foo<5>
to parameter Foo<I>
.
The reason template-name<TT>
is not a deduced context is fairly simple. If template-name<TT>
would be legal, then template-name
would have to take a template template parameter. That means it itself would have to be a template template template ("TTT"). There's only so much recursion in the language definition.
[edit]
In your example, you are deducing V
for U
to see if it's a specialization. Both are template templates. You are not trying to deduce whether Foo<U> is
Foo. Therefore your deduced context is
TT, not
template-name.`.
To answer point 2 of the comment, TT
is a deduced context because that form is listed explicitly. And what template-name<TT>
means is that TT
would have to be deducable when TT
is used as an argument to a known template. But what type of template accepts a template template parameter? That the hypothetical TTT
.
来源:https://stackoverflow.com/questions/48899131/is-template-namett-a-deduced-context