在Stroustrup起草了最初的模板规范之后,人们更加无忧无虑的使用了class很长一段时间。可是,随着标准化C++工作的到来,人们发现了模板这样一种定义:
template <typename T>
void foo() {[]()
T::iterator iter;
// ...
}
在上例代码中T本身已经是模板的类型参数,它只有等到模板实例化时才会知道是哪种类型,更不用说由T定义的内部的iterator。
编译器不知道第三行代码到底是,定义一个变量还是定义一个新类型,这样同一行代码能以两种完全不同的方式解释,而且在模板实例化之前,完全没有办法来区分它们,这绝对是滋生各种bug的温床。这时C++标准委员会再也忍不住了,与其到实例化时才能知道到底选择哪种方式来解释以上代码,委员会决定引入一个新的关键字,这就是typename。
c++标准定义到:
对于用于模板定义的依赖于模板参数的名称,只有在实例化的参数中存在这个类型名,或者这个名称前使用了typename关键字来修饰,编译器才会将该名称当成是类型。除了以上这两种情况,绝不会被当成是类型。
因此,如果你想直接告诉编译器T::iterator是类型而不是变量,只需用typename修饰:
template <typename T>
void foo() {
typename T::iterator iter;
// ...
}
通过加上typename关键字,这样编译器就可以确定T::iterator是一个类型,而不再需要等到实例化时期才能确定,因此消除了歧义
原文:https://www.cnblogs.com/keyayi/p/14786561.html