模板名称是推断的上下文吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板名称是推断的上下文吗?相关的知识,希望对你有一定的参考价值。
[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>
。这是编译器错误吗?
这一段充满了问题,包括你指出的问题。 Core issue 2328有一个很好的列表:
17.9.2.5 [temp.deduct.type]第8段的呈现方式导致规范不清楚,不必要的冗长和不完整。具体问题包括:
P
和A
拥有一套形式之一是什么意思?他们都必须有这种形式吗? (这不会发生;通常,只有P
包含模板参数)- 在介绍性的句子中,不是
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
s,如果一些位置没有T
就可以了”。所以我们有七个(!)形式的构造,除了三个位置都不包含T
的情况。- 我们有针对成员函数的指针的特殊情况规则,即使它们不是特殊情况,并且应该由成员指针和函数规则的规则涵盖。
- 我们不允许从模板模板参数中推导出模板模板参数的值 - 有
TT<T>
形式,TT<i>
形式,template-name<T>
形式和template-name<i>
形式,但没有TT<TT>
形式,也没有template-name<TT>
形式。
看起来编辑设法摆脱cv-list
,至少,自提出问题以来。它现在只是cv
。 (cv-list
有点搞笑,因为[语法]说-list后缀用于以逗号分隔的列表......)
这是正确的,template-name<TT>
不是推断的背景。这与此无关。简单的TT
是一个推断的背景,这就是你在这里所拥有的
推导的上下文template-name<I>
为非类型模板参数I
意味着当你有参数5
参数Foo<5>
时你可以推导出Foo<I>
。
template-name<TT>
不是推导上下文的原因相当简单。如果template-name<TT>
合法,那么template-name
必须采用模板模板参数。这意味着它本身必须是模板模板模板(“TTT”)。语言定义中只有这么多的递归。
[编辑]在你的例子中,你正在为V
推断U
,看看它是否是专业化的。两者都是模板模板。你不是要推断是否Foo<U> is
Foo. Therefore your deduced context is
TT, not
template-name。
为了回答评论的第2点,TT
是推断的上下文,因为该表单是明确列出的。 template-name<TT>
的意思是,当TT
被用作已知模板的参数时,TT
必须可以被推导出来。但是什么类型的模板接受模板模板参数?那假设的TTT
。
以上是关于模板名称是推断的上下文吗?的主要内容,如果未能解决你的问题,请参考以下文章