02 模板编程

02 模板编程

模板函数

​ 模板函数就是一种,能够将类型抽象出来的函数。

template <typename T>
void swap(T& lhs, T& rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}

int a = 1, b = 2;
swap(a, b);

template <typename T1, typename T2>
void print(T1& t1, T2& t2)
{
std::cout << t1 << t2 << '\n';
}


print(a, b);
double c = 2.2;
print(a, c);

模板类

​ 模板类也是同样的道理。

template <typename T>
class A
{
T data;
public:
void setData(T _data) { data = _data; }
void print() { std::cout << data << '\n'; }
};

//////////////////////////////
A<int> a_int;
a_int.setData(100);
a_int.print();

//////////////////////////////
A<double> a_double;
a_double.setData(100);
a_double.print();

为什么要有模板?

​ 这个问题其实和为什么有函数是一样的。以前在没有函数的年代里,人们总是要写重复的代码,为了将重复的逻辑抽象出来,于是就有了函数。

​ 现在,人们同样是要写重复的逻辑,但是却因为只是类型不同而需要重写一个函数。比如一个int类型的快排和一个double类型的快排一样,它们的核心逻辑没有丝毫变换,仅仅是类型不同就要重写一个函数。于是人们就想要将类型抽象出来,也就变成了模板。

#include <iostream>
#include <vector>

template <typename T>
int partition(std::vector<T>& arr, int low, int high) {
T pivot = arr[high]; // 选择最后一个元素作为基准
int i = (low - 1); // Index of smaller element

for (int j = low; j <= high - 1; j++) {
// 如果当前元素小于或等于pivot
if (arr[j] <= pivot) {
i++; // increment index of smaller element
std::swap(arr[i], arr[j]);
}
}
std::swap(arr[i + 1], arr[high]);
return (i + 1);
}

template <typename T>
void quickSort(std::vector<T>& arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);

quickSort(arr, low, pi - 1); // Before pi
quickSort(arr, pi + 1, high); // After pi
}
}

// 打印数组
template <typename T>
void printArray(const std::vector<T>& arr) {
for (int i = 0; i < arr.size(); i++)
std::cout << arr[i] << " ";
std::cout << std::endl;
}

// 测试模板版本的快速排序
int main() {
std::vector<int> intArray = {10, 7, 8, 9, 1, 5};
std::vector<double> doubleArray = {10.5, 7.2, 8.9, 9.1, 1.5, 5.3};

std::cout << "Original int array: ";
printArray(intArray);

std::cout << "Sorted int array: ";
quickSort(intArray, 0, intArray.size() - 1);
printArray(intArray);

std::cout << "Original double array: ";
printArray(doubleArray);

std::cout << "Sorted double array: ";
quickSort(doubleArray, 0, doubleArray.size() - 1);
printArray(doubleArray);

return 0;
}

模板的某些应用

​ 有时候模板也非常有用。比如我想要统一将传入的数据变成std::string类型:

template <typename T>
std::string m_to_string(T& t)
{
return std::to_string(t);
}

template <> // 模板特化
std::string m_to_string<std::string>(std::string& t)
{
return t;
}

练习

  • 写一个冒泡排序,要求支持模板。template <typename T> void sort(T *arr, int size){xxxxxx}

  • 用vector完成一个任务:添加5个人的成绩,找到输入的那个成绩。

  • 用map和list实现同样功能