泛型编程【函数模板】

文章目录

  • 模板概论
  • 模板的分类
  • 类属
  • 函数模板
  • 函数模板的使用
  • 使用模板函数来实现选择排序
  • 函数模板和函数模板
  • 调用规则(主要体现在函数重载方面)
  • 模板机制
  • 模板的局限性

模板概论

c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表。这个通用函数就成为函数模板。凡是函数体相同的函数都可以用这个模板代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同函数的功能。

用模板是为了实现泛型,可以减轻编程的工作量,增强函数的重用性

泛型编程主要利用的技术就是模板
模板分为 函数模板和类模板
模板的思想: 将类型参数化

模板的分类

  • 函数模板
  • 类模板

类属

  • 类型参数化,又称参数模板

函数模板

实现类型的参数化

语法

//class = typename 随便用一个就可以

//这两行不能分开
template <typename T>
void MySwap(T &a,T &b)
{
	T temp = a;
	a = b;
	b = temp;
}

void test()
{	
	int a = 10;
	int b = 20;
	MySwap(a,b);  //自动类型推导

	double d1 = 3.14;
	double d2 = 2.14;
	MySwap<double>(d1,d2);  //显示指定类型
}

函数模板的使用

  • 自动类型推导
  • 显式指定类型

注意: 使用自动类型推导时必须推导出来一样的类型才能正确使用
模板不可以独立使用,必须要指定出T的类型才能调用

使用模板函数来实现选择排序


template <typename T>
void MySwap(T &a,T &b)
{
	T temp = a;
	a = b;
	b = temp;
}

template <class T>
void PrintArray(T arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}

template <typename T>
void MySort(T arr[],int len)
{
	for(int i = 0; i < len; ++i)
	{
		int max = i;
		for(int j = i+1; j < len; ++j)
		{
			if(arr[max] < arr[j])
			{
				max =j;
			}	
		}
		if(max != i)
		{
			MySwap(arr[max],arr[i]);
		}
	}
}

void test()
{
	int arr[] = { 1,2,5,8,9,7,3,6,4 };
	int len = sizeof(arr) / sizeof(arr[0]);

	MySort(arr, len);
	PrintArray(arr, len);  

}


函数模板和函数模板

区别: 普通函数可以发生隐式类型转换
函数模板使用自动类型推导时,不可以发生隐式类型转换

调用规则(主要体现在函数重载方面)

函数重载的条件:

  • 同一作用域下 ,函数名称相同
  • 参数类型不同
  • 参数顺序不用
  • 参数个数不用

调用规则

  1. 如果普通函数和函数模板都可以调用时,优先使用普通函数
  2. 如果想要强制调用函数模板,需要添加模板参数列表 <>
  3. 函数模板也可以发生函数重载]
  4. 如果函数模板可以产生更好的匹配,那么优先使用函数模板

模板机制

模板实现机制

  • 编译器并不是把函数模板处理成能够处理任何类型的函数(通过函数模板创建出来的函数为模板函数)
  • 函数模板通过具体的类型产生不同的函数
  • 编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译

模板的局限性

模板并不是可以处理任意类型的,针对特殊的数据类型,可以通过具体化的代码来解决

Class Person
{
public:
	int age;
	string name;		
}

template <class T>
bool MyCompare(T &a,T &b)
{
	if(a == b)
	{
		return true;
	]
	return false;
}
//针对Person写的代码(也可以使用函数重载处理这种问题)
template<> bool MyCompare(Person &a,Person &b)
{
		if(a.age == b.age && a.name == b.name)
		{
			return true;
		}
		return false;
}


void test()
{
	Person p1("alufei",18);
	Person p2("alufei",18);
	
	bool ret = MyCompare(p1,p2);	

}

你可能感兴趣的:(C++,c++,c语言,函数模板)