C++---模板

(一)函数模板

(1)模板编译过程(在编译期间):

  • 在定义点只编译模板头部
  • 在调用点编译模板函数

template(关键字)<模板参数列表>

template:定义模板类型参数,指明模板中的类型

template<typename T>
T Sum(T a , T b)
{
    couture<<typeid(T).name<<endl;
    return a+b;
}
int main()
{
   Sum<int>(10,20)//使用方法
   return 0;
}

(2)模板的实例化

模板实参传递给模板形参,int替换T。替换过程就叫模板实例化,在编译期间完成typedef替换。

int Sum(int a , int b)

{
    couture<<typeid(int).name<<endl;
    return a+b;
}

(3)模板函数

模板实例化生成的函数就是模板函数

(4)模板实参推演

通过参数的类型推演出模板的参数类型,两个参数类型相同都为int。模板实例化生成int版本的模板函数。

注意事项:当这样调用时Sum(10,20.1)编译器报错类型不明确。所以1、不能让编译器产生二义性2、要有实参。

(5)模板特例化

模板不能满足特殊类型的需求,例如:

template <typename T>
bool Compare(T a, T b)
{
	return a > b;
}
int main()
{
	Compare<char*>("hello", "world");
}
//生成的模板函数
bool Compare(char* a, char* b)//比较的是地址的值并不是比较的是值
{
	return a > b;
}

需要实现特例化的版本:

template<>
bool Compare<char*>(char* a,char* b)
{
     return strcmp(a,b) > 0;
}
  • 完全特例化:函数模板 char*   类模板char*
  • 部分特例化:类模板T*

部分函数特例化:较小函数不满足,对函数实现特例化;

较多函数不满足,对所有函数实现特例化

(6)模板的类型参数

<>能存放模板类型参数

#include<iostream>
using namespace std;
template <typename T>
void Sort(T *arr, int len)
{
	for(int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j+ 1])
			{ 
				T temp;
				temp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
	}
}
template < typename Type >
void Show(Type *arr, int len)
{
	for (int i = 0; i < len; i++)
		cout << arr[i] << " ";
}
int main()
{
	int arr[10] = {36,53,28,95,25,4,56,34,5,67};
	int len = sizeof(arr) / sizeof(arr[0]);
	Sort<int>(arr, len);
	Show<int>(arr, len);

}

(7)模板的非类型参数

  • 模板的非类型参数是一个常量
  • 不能用float,double等类型
#include<iostream>
using namespace std;
template <typename T,int LEN>
void Sort(T *arr)
{
	for (int i = 0; i < LEN - 1; i++)
	{
		for (int j = 0; j < LEN - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				T temp;
				temp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
	}
}
template < typename Type>
void Show(Type *arr,int len)
{
	for (int i = 0; i < len; i++)
		cout << arr[i] << " ";
}
int main()
{
	int arr[10] = { 36, 53, 28, 95, 25, 4, 56, 34, 5, 67 };
	const int len = sizeof(arr) / sizeof(arr[0]);//非类型参数是常量,不能做左值,要用const修饰
	Sort<int,len>(arr);
	Show<int>(arr,len);
}

(8)模板默认值C++11

(9)接收模板的不明确类型的返回值用auto

(10)模板重载

调用的优先级:普通版本、模板特例化版本、模板实例化版本

(二)类模板

构造函数和析构函数可以缺省类型参数,其他地方不要缺省。

类模板实例化:选择实例化,调用的时候对要调用的成员方法进行实例化。

#include<iostream>
using namespace std;

template <typename T>
class Clink;//前置声明
template <typename _Vty>
class Node//类模板名
{
public:
	//模板名<类型参数>==类名
	Node<_Vty>(_Vty val = _Vty()) : value(val), pnext(NULL)//零构造,零初始化并不清楚T是什么类型,就申请T类型的大小初始化为0。
                                                               //char*类型的零初始化,要使用typedef char* *CHAR char* p = *CHAR()
	{}
	~Node<_Vty>()
	{}
	/*template<typename E>//友元,Clink是Node的朋友,多对多 
	friend class Clink;*/
    friend class Clink<_vty>;//一对一的友元
private:
	_Vty value;
	Node<_Vty>* pnext;
};
template <typename T>
class Clink
{
public:
	Clink()
	{
		phead = new Node<T>();
	}
	~Clink()
	{
		Node<T>* pCur = phead;
		Node<T>* pNext = pCur;
		while (pCur != NULL)
		{
			pNext = pCur->pnext;//不能访问私有成员
			delete pCur;
			pCur = pNext;
		}
		phead = NULL;
	}
	void Insert(T val);
	void Delete(T val);
	void Show()
	{
		Node<T>* pCur = phead->pnext;
		for (pCur; pCur != NULL; pCur = pCur->pnext)
		{
			cout << pCur->value;
		}
	}
private:
	Node<T>* phead;
	Node<T>* Find(T val);
};
//类模板成员方法在类外的定义
template <typename T>
void Clink<T>::Insert(T val)
{
	Node<T>*pnewnode = new Node<T>(val);
	pnewnode->pnext = phead->pnext;
	phead->pnext = pnewnode;
}
template <typename T>
Node<T>* Clink<T>::Find(T val)
{
	Node<T>*pCur = phead->pnext;
	while (pCur->pnext != NULL)
	{
		if (pCur->pnext->value == val)
		{
			return pCur;
		}
		pCur = pCur->pnext;
	}
	return NULL;
}
template <typename T>
void Clink<T>::Delete(T val)
{
	Node<T>* pfront = Find(val);
	if (pfront != NULL)
	{
		Node<T>*pCur = pfront->pnext;
		pfront->pnext = pCur->pnext;
		delete pCur;
	}
}
int main()
{
	Clink<int> link;//类模板使用时必须指定类型
	link.Insert(10);
	link.Show();
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值