[temp.deduct.type] paragraph 8列出了所有已推断的上下文,但似乎没有包含 template-name
<TT>
,其中 template-name
指的是到类模板,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和GCC 8.0.1,这意味着编译器认为部分特化比主模板更专业,这意味着主要模板中的U
和V
模板已成功推断foo<U, U>
。这是编译器错误吗?
答案 0 :(得分:6)
这一段充满了问题,包括你指出的问题。 Core issue 2328有一个不错的清单:
17.9.2.5 [temp.deduct.type]第8段的呈现方式 导致规范不清楚,不必要地冗长,并且 不完整的。具体问题包括:
P
和A
拥有一组表单之一是什么意思?他们都必须有这种形式吗? (这不会发生;通常情况下, 只有P
包含模板参数)在介绍性句子中,不是
< / LI>T
,TT
和i
应该是模板参数的名称而不是模板参数吗?在
T[i]
中,我们可以推断出i
,但不是T
(T
只能以T[integer-constant]
的形式推断出来什么是
integer-constant
应该是什么?什么是
cv-list
?为什么我们不能从
const T
中推断T
? (显然,如果两种类型或两种类型都没有cv-list
,您只能推断出,无论是什么cv-list
是。)我们有极端的冗余,因为,例如,没有办法说“在
T (T::*)(T)
中,你可以推断出T
中的任何一个,而且没关系 如果某些职位没有T
“。所以我们有七个(!)表格 对于所有情况,除了没有的情况之外的所有情况 三个职位包含T
。我们有针对成员函数指针的特殊情况规则,即使它们不是特殊情况,应该被规则涵盖 指向成员的指针和功能规则。
我们不允许从模板模板参数中推断出模板模板参数的值 - 有一个
TT<T>
表单,一个TT<i>
形式,template-name<T>
形式,和template-name<i>
表单,但没有TT<TT>
表单 也不是template-name<TT>
形式。
看起来编辑设法摆脱 cv-list
,至少,因为提交了问题。它现在只是 cv
。 ( cv-list
有点搞笑,因为[语法]说 -list 后缀用于以逗号分隔的列表...)
答案 1 :(得分:-1)
这是正确的,template-name<TT>
不推断的上下文。这与此无关。普通TT
是推导出的背景,这就是你在这里所拥有的
非类型模板参数template-name<I>
的推断上下文I
表示当参数5
有参数Foo<5>
时,您可以推导Foo<I>
。
template-name<TT>
不是推断的上下文的原因相当简单。如果template-name<TT>
合法,则template-name
必须采用模板模板参数。这意味着它本身必须是模板模板模板(&#34; TTT&#34;)。语言定义中只有这么多的递归。
[编辑]
在您的示例中,您要为V
推断U
以查看它是否为专业化。两者都是模板模板。您不是要推断Foo<U> is
Foo . Therefore your deduced context is
TT , not
模板名称。
要回答评论的第2点,TT
是推断的上下文,因为该表单已明确列出。 template-name<TT>
的含义是,当TT
用作已知模板的参数时,TT
必须可以被推导出来。但是什么类型的模板接受模板模板参数?这是假设的TTT
。