C++:函数模板

两个数求和:

1)C语言泛型 void*  [ )--------------半开半闭,易越界

2)函数重载 ---------------------------类型有限制

3)宏-------------------------------------不安全

4)C++泛型----------------------适宜

 c++泛型用模板来实现、

1.函数模板:
自己定义的代码叫函数模板

template<typename T>
T Sum(T a, T b)
{
	cout << typeid(T).name() << endl;
	return a + b;
}

模板编译:

定义点:编译模板的头部

调用点编译:编译模板函数

2.模板函数:

假如实参传入为int ,int替换成T,实例化后生成的函数叫做模板函数。替换属于 typedef的替换

int Sum(int a, int b)
{
	cout << typeid(int).name() << endl;
	return a + b;
}

3.模板的实例化:

实参类型替换形参类型的过程叫做模板的实例化。

4.模板的实参推演:

没有传入实参类型,推演其类型,编译器通过()中的值与模板中形参进行匹配,编译器可以辨识数值为什么类型。

模板实参推演限制:

1)不能让编译器产生二义性

2)有实参

template<typename T>
T Get()
{
    T tmp;
    return tmp;
}

这个没有实参,就有错误

参考代码:

#include<iostream>

using namespace std;

/*    
<>模板类型参数列表   typenmae说明后面是一个类型
*/

template<typename T>//形参虚拟的类型
T Sum(T a, T b)//两个数求和
{
	cout << typeid(T).name() << endl;
	return a + b;
}

int main()
{
	Sum<int>(10, 20);//   <>模板实参列表  实参是具体的类型,把类型参数化了
	Sum<double>(10.1, 20.1);
	Sum<char>('a', 'b');
	Sum(10, 20);//没有传入实参类型,推演其类型,编译器通过()中的值与模板中形参进行匹配
	//Sum(10.1,20); 报错,产生二义性

	return 0;
}

5.模板的非类型参数

1)int len = sizeof(arr) / sizeof(arr[0]);//报错

修改:const int len = sizeof(arr)/ sizeof (arr[0]);

2)template<typename T,float LEN>   //LEN 非类型参数

模板的非类型参数特点:

1)常量

2)内置类型中不能用float,double 

代码:

#include<iostream>

using namespace std;


template<typename T>//冒泡排序
void Sort1(T *arr,int len)//一个虚假类型,一个自定义类型
{
	T temp;
	for (int i = 0; i < len-1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}


template<typename T,int LEN>   // T 类型参数  LEN 非类型参数
void Sort2(T *arr)
{
	T temp;
	for (int i = 0; i < LEN - 1; i++)
	{
		for (int j = 0; j < LEN - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}

}


template<typename T>
void Show(T *arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}

int main()
{

	int arr[] = { 10,9,87,6,45,4,6,8,5,32 };
	//int len = sizeof(arr) / sizeof(arr[0]);
	const int len = sizeof(arr)/ sizeof (arr[0]);
	Show<int>(arr, len);
	Sort1<int>(arr, len);//Sort(arr,len)
	Show<int>(arr, len);
	Sort2<int,len>(arr);
	Show<int>(arr, len);
	return 0;
}

6.模板的特例化

完全特例化

函数模板支持完全特例化 

部分特例化

类模板不仅支持完全特例化,也支持部分特例化

函数模板不能满足某些需求,需单独处理

#include<iostream>

using namespace std;

template<typename T>
bool Compare(T a, T b)
{
	cout << "template<typename T>"<<endl;
	return a > b;
}

template<>    //此时不是模板,已进化为函数,会编译
bool Compare<char*>(char* a, char *b)// Compare<char*>构成函数名
{
	cout << "template<>"<<endl;
	return strcmp(a, b) > 0;
}

int main()
{
	Compare<int>(10, 20);
	Compare<double>(10.1, 20.1);
	Compare<char*>("hello", "world");
	return 0;
}

特例化注意事项:

错误解释:

上面:const 修饰 a,b ,修饰 T类型  T类型 是 char*

下面:cnnst 修饰 *a , *b  修饰 char类型 

原因:特例化实现的逻辑和模板实例化实现的逻辑不一样

修改:

7.模板的重载

#include<iostream>

using namespace std;

//模板函数
template<typename T>
bool Compare(const T a,const T b)
{
	cout << "template<typename T>"<<endl;
	return a > b;
}

//普通函数
bool Compare(char *a, char *b)
{
	cout << "Compare()" << endl;
	return strcmp(a, b) > 0;
}

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

int main()
{
	Compare<int>(10, 20);
	Compare<double>(10.1, 20.1);
	Compare<char*>("hello", "world");//调用特例化
	Compare("hello", "world");//调用实例化
	return 0;
}

优先级:普通函数>特例化>函数模板

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值