模板名称<tt>是推导的上下文吗?

时间:2018-02-21 06:05:41

标签: c++ templates language-lawyer template-deduction

[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>。这是编译器错误吗?

2 个答案:

答案 0 :(得分:6)

这一段充满了问题,包括你指出的问题。 Core issue 2328有一个不错的清单:

  

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

     
      
  • PA拥有一组表单之一是什么意思?他们都必须有这种形式吗? (这不会发生;通常情况下,   只有P包含模板参数)

  •   
  • 在介绍性句子中,不是TTTi应该是模板参数的名称而不是模板参数吗?

    < / LI>   
  • T[i]中,我们可以推断出i,但不是TT只能以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