泛型编程 (Generic Programming)

泛型编程最初提出时的动机很简单直接:发明一种语言机制,能够帮助实现一个通用的标准容器库.

泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型即是指具有在多种数据类型上皆可操作的含义,与模板有些相似。

STL巨大,而且可以扩充,它包含很多计算机基本算法和数据结构,而且将算法与数据结构完全分离,其中算法是泛型的,不与任何特定数据结构或对象类型系在一起。

关于泛型的理解可以总结下面的一句话: 它是把数据类型作为一种参数传递进来。

一. 模板函数

普通单int型的Swap函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <bits/stdc++.h>
using namespace std;

void Swap(int &a, int &b) {
int c = a;
a = b;
b = c;
}

int main() {
int n, m;
cin >> n >> m;
Swap(n, m);
cout << n << ' ' << m;
return 0;
}

使用模板函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <bits/stdc++.h>
using namespace std;

template <class T>
void Swap(T& a, T& b) {
T c = a;
a = b;
b = c;
}

int main() {
int n, m;
cin >> n >> m;
Swap(n, m); //或者自己传入变量类型 Swap<int>(n, m);
cout << n << ' ' << m;
return 0;
}

Ps :多个类型参数模板函数:

1
2
3
4
5
template <class T1, class T2>
T2 MyFun(T1 a, T2 b) {
cout << a << ' ' << b;
return b;
}

可以重载, 只要他们的形参表或类型参数表不同即可.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T1, class T2>
void print(T1 a, T2 b) {
cout << a << ' ' << b << '\n';
}

template <class T>
void print(T a, T b) {
cout << a << ' ' << b << '\n';
}

template <class T, class T2>
void print(T a, T b) {
cout << a << ' ' << b << '\n';
}

模板函数重载有点混乱.

https://zhuanlan.zhihu.com/p/101898043

在有多个函数和函数模板名字相同的情况下,编译器如下规则处理一条函数调用语句: 1. 先找参数完全匹配的普通函数(非由模板实例化而得的函数); 2. 再找参数完全匹配的模板函数; 3. 再找实参数经过自动类型转换后能够匹配的普通函数; 4. 上面的都找不到,则报错。

二. 类模板

1
2
3
4
5
template <class 类型参数1class 类型参数2,...> //类型参数表
class 类模板名
{
成员函数和成员变量
};

定义对象:

1
类模板名<真实类型参数表> 对象名(构造函数实参表);