C++ Template

发布时间 2023-08-20 16:47:47作者: OrzMiku

Template

模板,其他语言叫泛型,或者说是泛型的爷爷的爷爷(

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

直接上例子

例一

先看这段代码:

#include<iostream>

void print(std::string data) {
	std::cout << data << std::endl;
};

int main() {
	print("Miku");
	return 0;
}

这是一个打印内容的函数,但是如果我们想要打印一个整数就不行了,因为需要的参数是string。这时候就有小伙伴说了,函数重载啊。确实可以,下面是函数重载的代码:

#include<iostream>

void print(std::string data) {
	std::cout << data << std::endl;
};

void print(int data) {
	std::cout << data << std::endl;
};
int main() {
	print("Miku");
	print(39);
	return 0;
}

没任何问题,如果我们还需要对浮点数支持,代码就会变成下面这样:

#include<iostream>

void print(std::string data) {
	std::cout << data << std::endl;
};

void print(int data) {
	std::cout << data << std::endl;
};

void print(float data) {
	std::cout << data << std::endl;
};

void print(double data) {
	std::cout << data << std::endl;
};

int main() {
	print("Miku");
	print(39);
	print(39.0);
	return 0;
}

那如果还有更多的数据类型需要支持呢?就需要很多很多的重载函数。假如我们需要修改输出格式,我们就需要修改每一个重载函数。如:

#include<iostream>

void print(std::string data) {
	std::cout << "Log:" << data << std::endl;
};

void print(int data) {
	std::cout << "Log:" << data << std::endl;
};

void print(float data) {
	std::cout << "Log:" << data << std::endl;
};

void print(double data) {
	std::cout << "Log:" << data << std::endl;
};

int main() {
	print("Miku");
	print(39);
	print(39.0);
	return 0;
}

这个时候template就排上用场了(注意不仅仅这一个用途,后面还会说),我们的代码可以写成这样:

#include<iostream>

template <typename T> void print(T data) {
	std::cout << "Log:" << data << std::endl;
};

int main() {
	print("Miku");
	print(39);
	print(39.0);
	return 0;
}

这里将print函数定义为模板,typename T表示有一个类型T,T是什么还不知道。我们在实际调用的时候,传了什么类型,T就是什么类型(这里的typename也可以写成class,但是没typename直观)。

编译器在编译到 print("Miku");时,就为我们写了一段代码:

void print(std::string data) {
	std::cout << "Log:" << data << std::endl;
};

然后 print("Miku");就可以正常使用了。

当然我们也可以指定print的类型:

#include<iostream>

template <typename T> void print(T data) {
	std::cout << "Log:" << data << std::endl;
};

int main() {
	print("Miku");
	print(39);
	print <double> (39.0);
	return 0;
}

print <double> (39.0); 指定了 Tdouble

例二

上面 print <double> (39.0);这种格式有没有很眼熟?我们在使用C++的 array 时,也有类似的表述:array<类型,长度> 变量名。我在这里复刻一下 array 类:

#include<iostream>

template <typename T> void print(T data) {
	std::cout << "Log:" << data << std::endl;
};

template <class T, int N> class array {
private:
	T arr[N];
public:
	int size() {
		return N;
	}
};

int main() {
	print("Miku");
	print(39);
	print <double> (39.0);
	array<std::string, 10> strArr;
	std::cout << strArr.size() << std::endl;
	return 0;
}

当然我没有实现array类的各种功能,只是说明了一下template在这里的用途。不仅仅可以有typename(or class),也可以有别的类型。

这只是冰山一角,未完待续...(后续也会更新到这篇文章里)