为什么嵌套类型的基类不需要`typename`?

时间:2019-09-11 07:07:28

标签: c++ templates inheritance

我很惊讶地发现,当依赖类型出现为基类时,不必添加typename

struct B {};

struct wr
{ typedef B type; };

template<class T>
struct A : T::type
{};

int main()
{
    A<wr> a;
    (void)a;
}

为什么typename前面不需要T::type

3 个答案:

答案 0 :(得分:19)

  

为什么typename前面不需要T::type

因为您不能从值继承。您使用typename告诉编译器给定的嵌套标识符是一种类型,但是对于继承,无论如何都必须如此,因此可以忽略它-这就是语言为typename提供异常的原因-基本说明符规则。来自cppreference(重点是我):

  

从属名称的typename消歧符

     

在模板(包括别名模板)的声明或定义中,除非使用关键字typename或<,否则不将其视为当前实例的成员并且依赖于模板参数的名称不视为类型。 strong>除非已将其建立为类型名称,例如使用typedef声明或用来命名基类

请注意,我们将获得更多可以省略typename的地方,请参见P0634

答案 1 :(得分:13)

这是一个特例,正如其他人指出的那样。在此引用标准:

  

[温度]

     

5限定名称,用作类或十进制类型或   elaborated-type-specifier被隐式假定为命名类型,   无需使用typename关键字。在嵌套名称说明符中   立即包含一个嵌套名称说明符,该说明符取决于   模板参数,标识符或simple-template-id是隐式的   假定不使用typename关键字来命名类型。   [注意:这些语法不允许使用typename关键字   结构体。 —尾注]

随着C ++ 20的到来,对于typename的需求将会有更多的例外。

答案 2 :(得分:5)

仅在需要告诉编译器期望类型而不是其他类型时,才需要使用typename

由于只能继承类型,因此没有歧义,因此typename是多余的。