一般来说,C++需要typename
因为它从C继承的不幸语法[*],如果没有非本地信息就不能说 - 例如 - 在名称A * B;
是否A
为类型(在这种情况下,这是一个声明B
为是否指向它(在这种情况下,这是一个乘法表达式 - 很可能,因为A
,如果没有非本地信息,你可以告诉所有人,可能是一个重载operator*
做一些奇怪事情的类的实例;-).
在大多数情况下,编译器确实具有消除歧义所需的非本地信息(尽管不幸的语法仍然意味着低级解析器需要来自保留符号表信息的更高级别层的反馈)...但是使用模板它不会(一般情况下,虽然在这种特殊情况下,专业化技术上可能是非法的,std::list
因此它::iterator
不是类型名称;-).
[*]不仅仅是我的观点,还有Ken Thompson和Rob Pikes的观点,目前我的同事们正在忙于设计和实现一种新的内部使用的编程语言:新的编程语言,而它的语法大部分都是C语言的,不重复C的语法设计错误 - 它是新语言(例如在古老的Pascal中),语法足以区分必须命名类型的标识符和不能标记类型的标识符;-).
一般来说,C++需要typename
因为它从C继承的不幸语法[*],如果没有非本地信息就不能说 - 例如 - 在名称A * B;
是否A
为类型(在这种情况下,这是一个声明B
为是否指向它(在这种情况下,这是一个乘法表达式 - 很可能,因为A
,如果没有非本地信息,你可以告诉所有人,可能是一个重载operator*
做一些奇怪事情的类的实例;-).
在大多数情况下,编译器确实具有消除歧义所需的非本地信息(尽管不幸的语法仍然意味着低级解析器需要来自保留符号表信息的更高级别层的反馈)...但是使用模板它不会(一般情况下,虽然在这种特殊情况下,专业化技术上可能是非法的,std::list
因此它::iterator
不是类型名称;-).
[*]不仅仅是我的观点,还有Ken Thompson和Rob Pikes的观点,目前我的同事们正在忙于设计和实现一种新的内部使用的编程语言:新的编程语言,而它的语法大部分都是C语言的,不重复C的语法设计错误 - 它是新语言(例如在古老的Pascal中),语法足以区分必须命名类型的标识符和不能标记类型的标识符;-).
如果您正在谈论typename
用于std::list
:
typename用于阐明这iterator
是在类中定义的类型std::list
.没有typename,std::list
将被视为静态成员.typename
每当依赖于模板参数的名称是类型时使用.