为什么仍然需要在使用语句的RHS中用typename来消歧一个依赖types?

我很清楚为什么需要为依赖types使用typename ,因为编译器可能无法在types和variables声明之间消除歧义,当它看到像T::type这样的东西时,请参阅这个答案,以获得很好的解释。 TL; DR :在像T::type * x;这样的expression式中T::type * x; ,编译器不能“知道” T::type是一个types,还是T一些特定的专门化中声明的variables。

然而,在类似的东西

 using type = T::type; 

没有什么暧昧的。 IMO, T::type 应该总是被parsing为一个types ,因为它是using语句的RHS的一部分。 但是,我们仍然需要在这里使用typename (至less根据gcc和clang)

 using type = typename T::type; 

住在Coliru,gcc 住在Coliru,铛

Visual C ++ 似乎接受没有types名称的代码 ,但我没有太多的信心,编译器完全符合标准(事实上,它有许多非标准的扩展,例如绑定右值到非const引用)。

问题 :为什么这不是C ++ 11及更高版本中的typename规则的例外?

没有困难的原因。 正如ralismark所说 ,今年讨论了一篇论文(C ++ 20,而不是17)。 有担忧,也有对立面:

  1. 它可以被看作是使语言不那么规律(正如codeshot所说的 ),但是新的想法是,消除歧义的typename会变得非常稀缺,从而在另一个方向上具有接近一致性。 (正如前面所说的 ,已经有一个以基类名称的forms出现的例外情况)
  2. 它可能会阻止可能的扩展(如TC报告 ),但扩展可能有自己的消歧,而不是负担常见的情况。

这份文件得到了有力的支持,新的规定很可能会在几个月内出现在工作草案中。

模板参数typesT不会,并且不能隐式地携带它的内部组件。 因此,当编译器查看未被实例化的模板时,T :: type基本上是一个新types,因此需要声明一个新的types名'T :: type'。

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