我很惊讶地发现,当依赖类型出现为基类时,不必添加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
?
答案 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
是多余的。