【问题标题】:Is template-name<TT> a deduced context?template-name<TT> 是推断的上下文吗?
【发布时间】:2018-07-31 15:12:56
【问题描述】:

[temp.deduct.type] paragraph 8 列出了所有推断的上下文,但似乎不包括 template-name&lt;TT&gt; 其中 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&lt;U, U&gt; .这是编译器错误吗?

【问题讨论】:

  • 我得告诉你,这个标准有时真的很令人沮丧。 It seems to be taking us right back to where we started
  • @StoryTeller 现在没有函数调用
  • 没错。这就是为什么那段令人沮丧。
  • 这条规则可能会导致某种形式的递归:[temp.deduct.type]/21
  • 看起来您发现了一个标准错误。 template-name&lt;TT&gt;TT&lt;TT&gt; 都需要在那里。真的,他们(几乎)一直是,(希望)永远都是。例如,您很难找到不支持something like this 的合理编译器。这不是模板条款中最严重的问题,但仍然是一个问题。

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


【解决方案1】:

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

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

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

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

  • T[i]中,看来我们可以推导出i,但不能推导出TT只能推导出T[<i>integer-constant</i>]的形式)

  • integer-constant 应该是什么?

  • 什么是cv-list

  • 为什么我们不能从T 推导出const T? (显然你只能推断出两种或两种类型都没有cv-list,不管是 cv-list 是。)

  • 我们有极端的冗余,因为例如,没有办法说“在T (T::*)(T),你可以推断出任何Ts,没关系 如果某些职位没有T”。所以我们有七个(!)表格 该构造的所有情况,除了没有 三个位置包含一个T

  • 我们对指向成员函数的指针有特殊情况规则,即使它们不是特殊情况并且应该包含在规则中 用于指向成员的指针和函数的规则。

  • 我们不允许从模板模板参数推断模板模板参数的值 - 有一个 TT&lt;T&gt; 形式,一个 TT&lt;i&gt; 表格、<i>template-name</i>&lt;T&gt; 表格和 <i>template-name</i>&lt;i&gt; 表单,但没有 TT&lt;TT&gt; 表单 也不是<i>template-name</i>&lt;TT&gt; 表单。

看起来编辑器设法摆脱了cv-list,至少,因为问题已提交。现在只是 cv。 (cv-list 有点大错特错,因为 [syntax] 表示 -list 后缀用于逗号分隔的列表...)

【讨论】:

  • 那么推导模板模板参数的规则也应该添加?似乎发生了巨大的变化。
  • @xskxzr 巨大?也许是为了规范。不适用于实现。
【解决方案2】:

这是正确的,template-name&lt;TT&gt; 不是推断的上下文。这与这里无关。 Plain TT 一个推断的上下文,这就是你在这里所拥有的

非类型模板参数I的推导上下文template-name&lt;I&gt;意味着当你有参数Foo&lt;5&gt;到参数Foo&lt;I&gt;时,你可以推导出5

template-name&lt;TT&gt; 不是推断上下文的原因相当简单。如果template-name&lt;TT&gt; 是合法的,那么template-name 必须采用模板模板参数。这意味着它本身必须是模板模板(“TTT”)。语言定义中只有这么多的递归。

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

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

【讨论】:

  • 1.你的意思是我的例子是编译器错误吗? 2. 为什么plain TT 是推断上下文? 3.“这意味着它本身必须是一个模板模板模板(“TTT”)。“你说的“它”是什么意思? template-name&lt;TT&gt; 本身是一个特化,而不是模板。
猜你喜欢
  • 2010-10-22
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-09-24
  • 1970-01-01
相关资源
最近更新 更多