template-name<TT> 是推导上下文吗?

Is template-name<TT> a deduced context?

[temp.deduct.type] paragraph 8 列出了所有推断的上下文,但它似乎不包括 template-name<TT> where template-name 指的是 class 模板,TT 指的是模板模板参数。这是推导上下文吗?

如果是,为什么?

如果不是,请考虑以下代码:

template<template<typename> class U, template<typename> class V>
struct foo {};

template<template<typename> class U>
struct foo<U, U> {}; 

int main() {}

此代码编译 under Clang 7.0.0 and GCC 8.0.1,这意味着编译器认为部分特化比主模板更特化,这意味着主模板中的 UV 被成功推导反对 foo<U, U>。这是编译器错误吗?

没错,template-name<TT>不是推导的上下文。这与这里无关。 Plain TT 一个推断的上下文,这就是你在这里

non-type 模板参数 I 的推导上下文 template-name<I> 意味着当参数 Foo<5> 参数 [=] 时可以推导 5 16=]。

template-name<TT> 不是推导上下文的原因很简单。如果 template-name<TT> 是合法的,那么 template-name 就必须采用模板模板参数。这意味着它本身必须是模板模板模板 ("TTT")。语言定义中只有这么多递归。

[编辑] 在您的示例中,您正在为 U 推导 V 以查看它是否是专业化。两者都是模板模板。你不是想推断是否 Foo<U> isFoo. Therefore your deduced context isTT, nottemplate-name.`。

要回答评论的第 2 点,TT 是一个推导的上下文,因为该形式已明确列出。 template-name<TT> 的意思是,当 TT 用作已知模板的参数时,TT 必须是可推导的。但是什么类型的模板接受模板模板参数呢?即假设的TTT.

这段有很多问题,包括你指出的那个。 Core issue 2328 有一个不错的列表:

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 and A to have one of a set of forms? Do they both have to have that form? (That doesn't happen; typically, only P contains template parameters)

  • In the introductory sentence, aren't T, TT, and i supposed to be the names of template parameters rather than template arguments?

  • In T[i], it appears we can deduce i, but not T (T can only be deduced in the form T[<i>integer-constant</i>])

  • What is an integer-constant supposed to be?

  • What is a cv-list?

  • Why can we not deduce const T from T? (Apparently you only get to deduce if both or neither type have a cv-list, whatever a cv-list is.)

  • We have extreme redundancy because, for instance, there is no way to say “in T (T::*)(T), you can deduce any of those Ts, and it's OK if some of the positions don't have a T”. So we have seven (!) forms of that construct, for all cases except the one where none of the three positions contain a T.

  • 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, a TT<i> form, a <i>template-name</i><T> form, and a <i>template-name</i><i> form, but no TT<TT> form nor <i>template-name</i><TT> form.

看起来编辑设法摆脱了 cv-list,至少,自从提交问题以来。现在只是 cv。 (cv-list 有点可笑的错误,因为 [语法] 说 -list 后缀用于 comma-separated 列表...)