模板名称是推断的上下文吗?

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.0GCC 8.0.1,这意味着编译器认为部分特化比主模板更专业,这意味着主模板中的UV成功地推导出foo<U, U>。这是编译器错误吗?

答案

这一段充满了问题,包括你指出的问题。 Core issue 2328有一个很好的列表:

17.9.2.5 [temp.deduct.type]第8段的呈现方式导致规范不清楚,不必要的冗长和不完整。具体问题包括:

  • PA拥有一套形式之一是什么意思?他们都必须有这种形式吗? (这不会发生;通常,只有P包含模板参数)
  • 在介绍性的句子中,不是TTTi应该是模板参数的名称而不是模板参数吗?
  • T[i],似乎我们可以推断i,但不是TT只能以T[integer-constant]的形式推断)
  • 什么是integer-constant应该是什么?
  • 什么是cv-list
  • 为什么我们不能从const T推断出T? (显然你只能推断,如果两种类型或两种类型都没有cv-list,无论cv-list是什么。)
  • 我们有极端的冗余,因为,例如,没有办法说“在T (T::*)(T),你可以推断出任何这些Ts,如果一些位置没有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> isFoo. Therefore your deduced context isTT, nottemplate-name。

为了回答评论的第2点,TT是推断的上下文,因为该表单是明确列出的。 template-name<TT>的意思是,当TT被用作已知模板的参数时,TT必须可以被推导出来。但是什么类型的模板接受模板模板参数?那假设的TTT

以上是关于模板名称是推断的上下文吗?的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段2——.vue文件的模板

VSCode自定义代码片段(vue主模板)

VSCode自定义代码片段1——vue主模板

vs 2010代码片段

vs 2010代码片段