c++模版中的dependent type和typename

Qualified and unqualified names

A qualified name is one that specifies a scope. For instance, in the following C++ program, the references to cout and endl are qualified names:

#include <iostream>
int main()  {
   std::cout << "Hello world!" << std::endl;
}

In both cases, the use of cout and endl began with std::.

Dependent and non-dependent names

A dependent name is a name that depends on a template parameter. Suppose we have the following declaration (not legal C++):

template <class T>
class MyClass {
   int i;
   vector<int> vi;
   vector<int>::iterator vitr;
   T t;
   vector<T> vt;
   vector<T>::iterator viter;
};

The types of the first three declarations are known at the time of the template declaration. However, the types of the second set of three declarations are not known until the point of instantiation, because they depend on the template parameter T.
The names T, vector<T>, and vector<T>::iterator are called dependent names, and the types they name are dependent types. The names used in the first three declarations are called non-dependent names, at the types are non-dependent types.
如下面一段代码中,const_iterator是从属类型,需要在它前面加上typename。否则,在某些情况下,会导致编译解析时产生二义性。

template<typename C>
bool lastGreaterThanFirst(const C& container){
	if(container.empty())
		return false;
	typename C::const_iterator begin(container.begin());
	typename C::const_iterator end(container.end());
	return *--end > *begin;
}

下面进行详细解释

template <class T>
void foo() {
   T::iterator * iter;
   ...
}

如果定义一个嵌套类型的类,

class ContainsAType {
   class iterator { ... }:
   ...
};

foo<ContainsAType>();  在这种情况下,iter将会被声明为一个指向T::iterator 类型的指针变量。
但是如果有人按以下方式声明类,

class ContainsAValue {
   static int iterator;
};

foo<ContainsAValue>(); 在这种情况下,将会有两种解析结果:一个叫做iter的变量,或者静态变量T::iterator。只有在实例化后才能消除他们之间的歧义。
Before a qualified dependent type, you need typename. Without typename, there is a C++ parsing rule that says that qualified dependent names should be parsed as non-types even if it leads to a syntax error. 
头疼,先mark下来。。
参考:http://pages.cs.wisc.edu/~driscoll/typename.html
 
 

Leave a Reply

Your email address will not be published. Required fields are marked *