请看一个例子:
template<typename T>
class Example {
public:
typename T::iterator getIterator();
};
哎,这里怎么多了一个typename
?
问:不要行吗?
答曰:不行。
问:为何?
答曰:因为T::iterator
有三种可能:
1. T类型有一个静态数据成员,其变量名为iterator;
2. T类型有一个静态成员函数,其函数名为iterator;
3. T类型里有一个嵌套类型,名为iterator。
编译器需要的是确定性!这么多可能,叫编译器怎么选择呢?
所以就有了那个typename
的存在,来明确地告诉编译器,这是第3种情况。
那么问题来了,编译器怎么分清楚1和2?
在实例化模板的时候,编译器自然可以很容易检查T类型到底是符合1的情况,还是2的情况(注意,1、2、3这三种情况的任意两种都是不可能同时发生的,因为类对成员的名字有限制),一个简单的if…else就可以搞定啦~
更详细的讲述,有兴趣请看这篇文章:http://feihu.me/blog/2014/the-origin-and-usage-of-typename/。