【问题标题】:Why does one still need to disambiguate a dependent type with typename in the RHS of a using statement?为什么仍然需要在 using 语句的 RHS 中消除依赖类型与 typename 的歧义?
【发布时间】:2017-06-10 00:55:39
【问题描述】:

我非常清楚为什么需要将typename 用于依赖类型,因为当编译器看到T::type 之类的内容时,它可能无法消除类型和变量声明之间的歧义,参见例如this answer 以获得很好的解释。 TL;DR:在像T::type * x; 这样的表达式中,编译器无法“知道”T::type 是一个类型还是可能是一个在T 的特定特化中声明的变量。

但是,像

using type = T::type;

没有什么模棱两可的。 IMO,T::type 应始终被解析为类型,因为它是 using 语句的 RHS 的一部分。但是,我们这里还是需要使用typename(至少根据gcc和clang),

using type = typename T::type;

Live on Coliru, gcc Live on Coliru, clang

Visual C++ seems to accept the code 没有 typename,但是我不太相信编译器完全符合标准(事实上,它有许多非标准扩展,例如将右值绑定到非 const 引用)。

问题:是否有任何理由说明这不是 C++11 及更高版本中 typename 规则的例外?

【问题讨论】:

  • 对于不赞成票的人:我不是为了获得分数而提问。如果你认为这个问题是废话,或者答案是微不足道的,至少让我知道。我非常希望看到现代 C++ 被简化,并且获得更简洁的语法是 (imo) 值得的。
  • 谢谢,这很有说服力。
  • @BenVoigt 有趣的是,VC++ 接受代码,rextester.com/HYWJH30088。但是(正如更新的编辑中提到的),我并不真正相信 VC++ 作为一个完全符合标准的编译器。感谢您的示例,是的,它具有相同的风格,但是使用 typedef 时,解析起来会有些困难。不过有了using,即使是我自己也能很快写出解析器。
  • 标准讨论中出现的理由之一?上次出现的原因是它阻止了潜在的进化路径(例如,使用using 声明表达式别名)。
  • 已经有一个提案 (p0634r0),虽然我不确定它的当前状态。

标签: c++ c++11 language-lawyer


【解决方案1】:

没有什么硬道理。作为 ralismark said,今年讨论了一篇论文(针对 C++20,而不是 17!)。有担忧,但也有反对意见:

  1. 可以将其视为使语言不那么规则(如codeshot said),但新的想法是消除typename 的歧义将变得非常罕见,以至于在另一个方向上几乎保持一致。 (作为has been said,已经有一个例外情况是基类名称的形式。)
  2. 它可以排除可能的扩展名(如T.C. reported),但扩展名可以有自己的歧义,而不是增加普通情况的负担。

论文得到大力支持,新规则可能会在几个月后出现在工作草案中。

【讨论】:

    【解决方案2】:

    模板参数类型 T 没有,也不能隐式携带它的内部组件。因此,当编译器查看未实例化的模板时,T::type 基本上是一种新类型,因此需要声明一个新的类型名 'T::type'。

    不幸的是,我认为这个问题将一直存在,直到标准包含成熟的概念。

    【讨论】:

    • 我记得现代 c++ 的第 9 项有你的问题作为选择使用而不是 typedef 的理由。也许这一次 vc 比 clang 更合拍?
    • 重点是你已经告诉编译器T::type 是一个类型,因为你不能在using 声明的RHS 上放置一个非类型。为什么你需要用typename 告诉它再次?在其他地方,消除歧义是必要的,但在这里不是。
    • 可以放一个非类型,它会发出诊断。如果他们改变这一点,这将使语言变得不规则,这可能会产生许多意想不到的后果,导致关闭进化的途径。目前T::a(对于类模板T)总是一个值,除非前面有typename,并且using在与一个值一起使用时总是会报错。这是一条常规规则,因此很容易解释、实施和规划语言演变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    相关资源
    最近更新 更多