typename的相关应用

typename的相关应用

#include <iostream>
using namespace std;

#if 0

typename的作用

1.泛型编程中与class的区别
template模版声明式中,class和typename这俩个关键字意义完全相同
template<class T> class Widget;
template<typename T> class Widget;

2.类型名提示符
在有些代码中必须加上typename来明确声明一个类型
如:
template<typename T>
void foo(const T& t)
{
	T::const_iterator it(t.begin());
	++it;
	int value = *it;
	cout << value;
}
此时编译的话会发生错误,因为编译器不知道T::const_iterator是一个类型
当模版被解析时,T还不确定,系统不知道它是一个类型名还是变量名所以需要
声明它为一个类型才能通过编译,应改为:
typename T::const_iterator it(t.begin());

3.嵌套从属名称的声明
事实上类型T::const_iterator依赖于模板参数T, 模板中依赖于模板参数的名
称称为从属名称(dependent name), 当一个从属名称嵌套在一个类里面时,
称为嵌套从属名称

嵌套从属名称是需要用typename声明的,其他的名称不可以用typename声明的
如下面是一个合法声明:
template<typename T>
void foo(const T& container, typename T::iterator iter);
如果在const T&前面也加typename则会出错 error : expected a qualified name after 'typename'

4.一个例外: 模板中的嵌套从属名称是需要typename声明的,然而有一个例外情况, 
在派生子类的基类列表中,以及构造函数的基类初始化列表中,不允许typename声明。
例如Derived<T>继承自Base<T>::Nested:

template<typename T>
class Derived : public Base<T>::Nested   //继承基类列表中不允许声明"typename"
{
public:
	explicit Derived(int x) : Base<T>::Nested(x) //基类初始化列表不允许声明"typename"
	{
		typename Base<T>::Nested tmp;  //这里是要声明的
	}
};

5.typedef来给嵌套从属名称起别名
template<typename IterT>
void workWithIterator(IterT it)
{
	typedef typename std::iterator_traits<Iter>::value_type value_type;
	value_type tmp(*it);
}

#endif

猜你喜欢

转载自blog.csdn.net/SwordArcher/article/details/81394212