【C++】详细解读:typename声明模板中的一个类型

用C++封装一个不带头结点的单链表

要求:用嵌套类型的方式

template<typename T>
class CLink//模板
{
public:
	CLink()
	{
		phead = NULL;
	}
	~CLink()
	{
		Node* pCur = phead;
		Node* pNext;
		while (pCur != NULL)
		{
			pNext = pCur->pnext;
			delete pCur;
			pCur = pNext;
		}
		phead = NULL;
	}
	void insertHead(T val)
	{
		Node* pnewnode = new Node(val);

		pnewnode->pnext = phead;
		phead = pnewnode;
	}
	void insertTail(T val)
	{
		Node* pnewnode = new Node(val);
		if (phead == NULL)
		{
			phead = pnewnode;
		}
		else
		{
			Node* ptail = phead;
			while (ptail->pnext != NULL)
			{
				ptail = ptail->pnext;
			}
			ptail->pnext = pnewnode;
		}
	}
	void Show()
	{
		Node* pCur = phead;
		while (pCur != NULL)
		{
			std::cout << pCur->mdata << " ";
			pCur = pCur->pnext;
		}
		std::cout << std::endl;
	}
	
private:
	class Node//类
	{
	public:
		Node(T val = T())
			:mdata(val), pnext(NULL)
		{}
	public://任意位置
		T mdata;
		Node* pnext;
	};
	Node* phead;//phead  头指针
};

1、以嵌套的方式的好处是:
在使用两个不同的类时,不用考虑是否存在不能访问某一个类私有成员变量的情况,也就是不用写友元函数。
2、此时class作为一个模板,而Node作为一个类类型

如果要在函数模板中写一个查询函数

要求:返回查询到的第一个数组当前的结点位置
一般我们会直接在模板下写:

Node* find(T val)
{
	Node* pCur = phead;
	while (pCur != NULL)
	{
		if (pCur->mdata == val)
		{
			return pCur;
		}
		pCur = pCur->pnext;
	}
	return NULL;
}

1、编译器报错:
在这里插入图片描述
2、以上错误的原因是:
在C++中类的编译过程:
(1)类名
(2)成员名称
(3)成员函数的返回值和形参
(4)成员函数的函数体
在编译过程中,Node类是一个局部类,是在编译第3步完成后才进行编译的,但是在进行第3步时,编译器并不认识Node类
3、如果将查询函数放在类外实现,此时代码改为:

template<typename T>
CLink<T>::Node* CLink<T>::find(T val)
{
	Node* pCur = phead;
	while (pCur != NULL)
	{
		if (pCur->mdata == val)
		{
			return pCur;
		}
		pCur = pCur->pnext;
	}
	return NULL;
}

程序报错:
在这里插入图片描述
此时,Node还未编译,编译器并不知道Node是不是类型,
改正:给前面加上typename。

template<typename T>
typename CLink<T>::Node* CLink<T>::find(T val)

此时,第一个typename是定义了模板类型参数,第二个typename是声明了Node类是属于CLink类中的一个类型。
4、总结:
typename 声明模板中的一个类型

你可能感兴趣的:(C++)