C++ 模板是实现泛型编程的重要工具,提供了代码复用、类型安全和编译期多态的能力。模板不仅让程序适应任意数据类型,还能够通过类和函数的参数化,使得编译器在编译阶段自动生成代码,减少开发过程中的重复工作。本文将详细探讨模板的各个知识点,展示如何通过模板机制编写高效、灵活的代码。
模板是一种参数化机制,允许开发者编写与具体类型无关的通用代码。C++ 模板主要有两种类型:函数模板和类模板。
模板允许开发者编写逻辑结构相同但数据类型不同的代码,极大地提升了代码的复用性和可扩展性。
函数模板是为多个不同数据类型的函数创建的通用形式。通过 template
(或 template
) 关键字,开发者可以定义一个接受不同类型参数的通用函数。例如:
// 函数模板的定义,T 是模板参数,可以代表任意类型
template <typename T>
T add(T a, T b) {
return a + b;
}
该模板函数可以接受 int
、double
甚至 string
等不同类型的参数,编译器会根据传入参数的类型生成适当的函数版本。
调用模板函数与普通函数类似。编译器会根据传入参数的类型实例化模板,并生成相应的函数。代码如下:
int main() {
cout << add(1, 5) << endl; // 调用 int 类型的模板函数
cout << add(1.2, 2.3) << endl; // 调用 double 类型的模板函数
cout << add(string("Hello"), string(" World")) << endl; // 调用 string 类型的模板函数
}
模板函数的调用规则:
add(1, 2)
这样的显示模板实例化语法。template <typename T>
T myAdd(T a, T b) {
return a + b;
}
int my_add(int a, int b) {
return a + b;
}
int main() {
int x = 3;
char c = 'a';
cout << my_add(x, c) << endl; // 普通函数允许自动类型转换
// cout << myAdd(x, c) << endl; // 错误:模板函数不允许自动类型转换
}
模板除了可以接受类型参数外,还可以接受非类型参数。非类型模板参数的作用是在模板中传递一些固定的值,如数组的大小等。如下例所示,nmemb
是一个非类型模板参数:
// nmemb 是非类型模板参数,表示数组的大小
template <typename T, int nmemb>
void print_arr(T a[]) {
for (int i = 0; i < nmemb; i++)
cout << a[i] << " ";
cout << endl;
}
int main() {
int arr[5] = {
1, 2, 3, 4, 5};
print_arr<int, 5>(arr); // 打印数组
}
类模板类似于函数模板,允许创建可以操作不同类型数据的类。通过 template
,开发者可以定义通用类,允许在类的不同实例中使用不同的数据类型。例如:
template <typename T>
class Arr {
public:
Arr(int size = 0) {
this->p = new T[size];
this->size = size;
}
~Arr() {
delete