| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
1. //在C++中typename一般用来声明模板的模板参数(template parameter): template<typenameT> classX; //T是一个模板参数 2. /*但是还有一个关键的用法。首先是两个概念: 1). qualified name 例如:std::cout, std::endl;这样含有作用域符号(::)的就是限定名, 当我们用using声明将cout,endl引入到当前作用域之后就可以直接使用 这两个名称,这个时候cout,endl就不是限定名了。 2). dependent name dependent name是依赖于模板参数的类型,例如:*/ template<typenameT> classX { inti; std::vector<int> ivec; std::vector<int>::iterator iter; T type; std::vector<T> tvec; std::vector<T>::iterator titer; }; /* 前3个成员变量是不依赖于模板参数,所以是non-dependent name,后3个是dependent name ,直到实例化该模板的时候才会知道到底是什么类型。*/ //下面来讨论typename的第二种用法。现在假设我们有一个类如下: template<typenameT> classY { T::iterator *iter; ... }; /* 我们可能本意是想定义一个迭代器对象,例如我们如果用vector<int>来实例化这个模板,那么iter 则应该是一个迭代器指针,但是,如果我们用下面这个类来实例化这个模板:*/ classcType { staticintiterator; ... }; /* 那么T::iterator *iter会被编译器解释为两个数相乘。事实上,C++编译器会采用第二种解释方法 ,即使iterator的确是一个类型名。 为了避免这种矛盾,当我们适用qualified dependent name的时候,需要用typename来指出这是一个 类型名.即: */ template <typenameT> classY { typenameT::iterator *iter; typedeftypenameT::iterator iterator; //定义了Y::iterator类型名称 ... }; //typename 指出下面紧跟着的名称是一个类型 |
Summary: T::iterator this name, because iterator is specifically type or member variable depends on the type implementation of T, so when we
When you know that T::iterator is a type name, if we want to use this type name, we have to add TypeName before.
The use of TypeName