泛型编程
泛型编程是一种编程范式,旨在实现通用性和灵活性。它允许在编写代码时使用参数化类型,而不是具体的类型,从而使代码更加灵活和可重用。 在泛型编程中,代码可以被编写为与特定类型无关的形式,而是被设计成适用于多种类型。这使得同一段代码可以用于处理各种不同类型的数据,而无需为每种类型编写单独的代码。
举例:
在C语言中我们要交换两个数我们需要写一个swap函数,但是如果我们需要交换多个不同类型的数那就要写多个swap函数,那么这样大大降低了我们编程的效率,所以在C 中我们引入了泛型编程的概念,不管是函数还是类,我们都可以用一个模版来定义,我们需要用什么类型的参数直接替换就可以了,这样大大增加了我们编程的效率。
比如上面这张图,就是一个磨具,他为我们定好了形状,但是我们需要什么口味,需要什么食材都是我们自己定的,这就是模版。
函数模版
函数模板(Function Template)是C 中的一种机制,允许你编写通用的函数,能够处理多种不同类型的数据,而不需要针对每种类型写不同的函数。函数模板使用了泛型编程的思想,使得代码更加灵活和可重用。
举例:
代码语言:javascript复制template<typename T>
void Swap( T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
上面代码就是一个函数模版,一个函数家族,我们可以指定任意类型进行交换,但是我们不能用一个int类型和一个char类型进行交换,因为当我们用一个int类型和一个char类型交换时,编译器不知道T到底是改成char还是改成int,所以这种情况下我们可以利用模版的显示实例化 举例:
代码语言:javascript复制template<class T>
T Add(T a, T b)
{
return a b;
}
int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}
既然模版有显示实例化必定就有隐式实例化,下面我们来看看隐式实例化 举例:
代码语言:javascript复制template<class T>
T Add(T a, T b)
{
return a b;
}
int main(void)
{
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);
Add(d1, d2);
return 0;
}
模版参数的匹配原则
1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数。
代码语言:javascript复制// 专门处理int的加法函数
int Add(int left, int right)
{
return left right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
return left right;
}
void Test()
{
Add(1, 2); // 与非模板函数匹配,编译器不需要特化
Add<int>(1, 2); // 调用编译器特化的Add版本
}
2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
代码语言:javascript复制#include<iostream>
using namespace std;
template<class T>
T add(T a, T b)
{
return a b;
}
int add(int a, int b)
{
return a b;
}
int main()
{
int a, b;
cin >> a >> b;
int sum = add(a, b);
return 0;
}
从下面结果看,可以看见当模版存在时,非模版最匹配时,编译器会优先匹配非模版的函数
3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
类模版
类模版的定义格式
代码语言:javascript复制template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
类模版的实例化
我们先定义一个类:
代码语言:javascript复制template<class T>
class list
{
public:
private:
T* _a;
int _size;
int _cpacity;
};
我们来进行类的实例化
代码语言:javascript复制int main()
{
list<int> l1;
list<char> l2;
return 0;
}
总结
当模板被介绍到C 中时,它们彻底改变了编程的方式。函数模板和类模板为我们提供了一种通用的方法来编写代码,使得我们可以编写更加灵活、可重用的程序。通过使用模板,我们可以编写与特定类型无关的代码,从而提高了代码的灵活性和可维护性。函数模板允许我们编写可以处理多种类型的函数,而类模板则允许我们创建可以处理多种类型数据的类。在编写模板时,我们可以利用C 的强大类型系统来确保类型安全,并通过模板参数推断简化代码。总的来说,函数模板和类模板为我们提供了一种强大的工具,使得我们能够更加轻松地编写通用、高效的代码。