模板

第一类:函数模板

      1.函数模板:函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计。

      2.模板函数:在使用函数模板时,要将这个形参实例化为确定的数据类型。将类型形参实例化的参数称为模板实参;

                        用模板实参实例化的函数称为模板函数。模板函数的生成就是将函数模板的类型形参实例化的过程。

      3.模板的实例化:模板的实例化指函数模板  生成模板函数 的过程

      4.模板的实参推演:
            注意
                1.不能产生二义性
                2.保证有实参 

      5.模板的特例化(专用化):
                        当模板的逻辑不能满足特殊类型的需求,需要实现特例化:  
              1.完全特例化  或者叫 全特化: 例如:   函数模板  类模板
              2.部分特例化      偏特化: 
            注意事项
                特例化版本满足模板版本的逻辑

#include<iostream>

//普通的函数版本
bool Compare(char* cpa, char* cpb)
{
	std::cout << "bool Compare(char*, char*)" << std::endl;
	return strcmp(cpa, cpb) > 0;
}

//模板的版本
template<typename T>
bool Compare(T a, T b)
{
	std::cout << "template<typename T> bool Compare(T,T)" << std::endl;
	return a > b;
}

//模板特例化版本
template<>
bool Compare(char* a, char* b)
{
	std::cout << "template<> bool Compare(char*, char*)" << std::endl;
	return strcmp(a, b) > 0;
}

int main()
{
	char* p = "hello";
	char* q = "world";
	Compare(p, q);
	Compare<char*>("hello", "world");

	int a = 10;
	int b = 20;
	Compare<int>(10,20);
	return 0;
}

       6.类型参数:  template<class T> // T是类型模板参数
       7.非类型参数:  template<int val> //int val是非类型模板参数
            1.常量
            2.不允许浮点型

       

       8.模板的重载 :
            1.普通函数版本
            2.模板的版本
            3.模板的特例化版本

                精确匹配时的优先级:   1 > 3 > 2 

        9.模板的默认值 :   传递+推演  ==》 实例化
            函数模板的默认值  C++11特性
                1.取传递的值
                2.推演
                3.默认值
            且不必要从右向左依次赋予
            

//模板类型参数被赋默认值,且不必从右向左依次给默认值

template<typename F = int, typename S, typename T = int,typename R = float>
R Sum(F first, S second, T third)
{
	return first + second + third;
}

int main()
{
	auto rt = Sum<int>(10, 21.1, 15.5f);
	std::cout << typeid(rt).name() << std::endl;
	return 0;
}

        10.模板来接收不明确类型的返回
               auto 自适应调节类型
        11.显示实例化
               template
              模板一般写在.h文件中

 

第二类:类模板

   函数的模板的编译(这个特性的存在,所以在类中实现函数的时候需要测试每一个函数)
        1.定义点 只编译模板头部
        2.调用点 编译模板函数
   模板类型参数列表中   
        typename/class 定义类型参数
        1.类型参数
        2.非类型参数

//一个代码
template<typename T>
class CLink
{
public:
	template<typename E>
	friend class CLink;
public:
	CLink()
	{
		phead = new Node();
	}
	~CLink()
	{
		Node* pCur = phead;
		Node* pBack = pCur;
		while (pCur != NULL)
		{
			pBack = pCur->pnext;
			delete pCur;
			pCur = pBack;
		}
		phead = NULL;
	}
	//CLink(const CLink<T>& rhs);  //只支持原来的类型

	template<typename E> //用来支持由类似于  int->double的转换
	CLink(const CLink<E>& rhs)
	{
		phead = new Node();
		Node* pNewCur = phead;
		CLink<E>::Node* pCur = rhs.phead->pnext;
		while (pCur != NULL)
		{
			Node* pnewnode = new Node(pCur->mdata);
			pNewCur->pnext = pnewnode;
			pCur = pCur->pnext;
			pNewCur = pNewCur->pnext;
		}
	}

	void push_front(const T& val)
	{
		Node* pnewnode = new Node(val);

		pnewnode->pnext = phead->pnext;
		phead->pnext = pnewnode;
	}
	void Show()
	{
		Node* pCur = phead->pnext;
		while (pCur != NULL)
		{
			std::cout << pCur->mdata << " ";
			pCur = pCur->pnext;
		}
		std::cout << std::endl;
	}
	class Node;  //Node* find(const T& val)用到了Node这个类,在前面要声明Node这个类
	Node* find(const T& val)
	{
		Node* pCur = phead->pnext;
		while (pCur != NULL)
		{
			if (pCur->mdata == val)
			{
				return pCur;
			}
			pCur = pCur->pnext;
		}
		return NULL;
	}
private:
	class Node
	{
	public:
		Node(T val = T()) :mdata(val), pnext(NULL){};
	public:
		T mdata;
		Node* pnext;
	};
	Node* phead;
};

//template<typename T>  
//typename CLink<T>::Node* CLink<T>::find(const T& val)  //typename 说明这个 CLink<T>::Node* 是一个类型
//{
//	Node* pCur = phead->pnext;
//	while (pCur != NULL)
//	{
//		if (pCur->mdata == val)
//		{
//			return pCur;
//		}
//		pCur = pCur->pnext;
//	}
//	return NULL;
//}
int main()
{
	CLink<int> ilink;
	CLink<double> dlink(ilink);

	CLink<int> ilink2(ilink);
	return 0;
}
template<typename T1,
		 typename T2>
class Sum
{
public:
	Sum(T1 f, T2 s) :first_arg(f), second_arg(s){}
	T2 add()
	{
		return first_arg + second_arg;
	}
	template<typename R>
	R add()
	{
		return first_arg + second_arg;
	}
	template<>
	char* add<char*>()
	{
		char arr[1000] = { '\0' };
		std::cout << "Sum<char*,char*>" << std::endl;
		strcat(arr, first_arg);
		strcat(arr, second_arg);
		return arr;
	}
private:
	T1 first_arg;
	T2 second_arg;
};

/*
	全特化
*/
template<>
class Sum<char*,char*>
{
public:
	Sum(char* f, char* s) :first_arg(f), second_arg(s){}
	char* add()
	{
		char arr[1000] = { '\0'};
		std::cout << "Sum<char*,char*>" << std::endl;
		//char* ptmp = new char[strlen(first_arg) + strlen(second_arg) + 1]();
		strcat(arr, first_arg);
		strcat(arr, second_arg);
		return arr;
	}
private:
	char* first_arg;
	char* second_arg;
};
/*
	偏特化
*/
template<typename T1,
	typename T2>
class Sum<T1*, T2*>
{
public:
	Sum(T1* f, T2* s) :first_arg(f), second_arg(s){}
	T2 add()
	{
		std::cout << "template<T1,T2> class Sum<T1*,T2*>" << std::endl;
		return *first_arg + *second_arg;
	}
private:
	T1* first_arg;
	T2* second_arg;
};


int main()
{
	Sum<int, float> mysum(10, 20.1);
	float rt = mysum.add();
	std::cout << rt << std::endl;

	Sum<char*, char*> mysum1("hello", "world");
	char* rt1 = mysum1.add<char*>();
	std::cout << rt1 << std::endl;
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值