C++ 模板
C++ 模板是 C++ 中一个非常强大的功能,它允许程序员编写与类型无关的代码,即可以为不同类型的数据编写相同的代码。模板支持泛型编程,使得代码更具可复用性和可扩展性。C++ 模板主要有两种类型:函数模板和类模板。
1. 函数模板
函数模板允许你编写一个通用的函数,并能够对不同数据类型进行处理。当你使用某个类型调用模板函数时,编译器会自动生成适用于该类型的函数。
1.1 函数模板的定义
#include <iostream>
using namespace std;
// 定义一个函数模板,计算两个数的最大值
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
int main() {
cout << max(3, 5) << endl; // 使用 int 类型
cout << max(3.5, 2.5) << endl; // 使用 double 类型
cout << max('a', 'b') << endl; // 使用 char 类型
return 0;
}
输出:
5
3.5
b
说明:
template <typename T>:定义一个模板,其中T是占位符,可以代表任何类型。max(T a, T b):模板函数,能够处理不同类型的数据。
1.2 函数模板的类型推导
C++ 编译器可以根据传递给模板函数的实参自动推导出模板参数的类型。
#include <iostream>
using namespace std;
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
cout << add(3, 4) << endl; // T 被推导为 int
cout << add(3.5, 2.5) << endl; // T 被推导为 double
return 0;
}
输出:
7
6
说明:
- 编译器会根据
3和4推导出T为int,根据3.5和2.5推导出T为double。
1.3 函数模板的显式类型指定
尽管 C++ 支持类型推导,但也可以显式指定模板参数的类型。
#include <iostream>
using namespace std;
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
cout << add<int>(3, 4) << endl; // 显式指定模板类型为 int
cout << add<double>(3.5, 2.5) << endl; // 显式指定模板类型为 double
return 0;
}
输出:
7
6
2. 类模板
类模板与函数模板类似,它允许我们定义一个通用类,使用时可以指定不同的类型。
2.1 类模板的定义
#include <iostream>
using namespace std;
// 定义一个类模板,表示一个盒子,能存放任意类型的元素
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() { return value; }
};
int main() {
Box<int> intBox(10); // 创建一个存放 int 类型的 Box
Box<double> doubleBox(3.14); // 创建一个存放 double 类型的 Box
cout << intBox.getValue() << endl; // 输出:10
cout << doubleBox.getValue() << endl; // 输出:3.14
return 0;
}
输出:
10
3.14
说明:
template <typename T>:定义了一个类模板,T可以代表任意类型。Box(int v):类的构造函数,初始化value。T getValue():返回存储的值。
2.2 类模板的多个参数
模板不仅可以有一个类型参数,还可以有多个类型参数。
#include <iostream>
using namespace std;
// 定义一个类模板,表示一个箱子,能存放两个不同类型的元素
template <typename T1, typename T2>
class Pair {
private:
T1 first;
T2 second;
public:
Pair(T1 f, T2 s) : first(f), second(s) {}
T1 getFirst() { return first; }
T2 getSecond() { return second; }
};
int main() {
Pair<int, double> p(3, 4.5); // 创建一个存放 int 和 double 类型的 Pair
cout << p.getFirst() << ", " << p.getSecond() << endl; // 输出:3, 4.5
return 0;
}
输出:
3, 4.5
说明:
template <typename T1, typename T2>:定义一个类模板,它接收两个类型参数T1和T2。Pair<int, double>:创建一个Pair类型的对象,它存储一个int和一个double类型的值。
2.3 默认模板参数
C++ 允许在类模板中为模板参数指定默认类型。
#include <iostream>
using namespace std;
// 定义一个类模板,带有默认类型参数
template <typename T = int>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() { return value; }
};
int main() {
Box<> intBox(10); // 使用默认的 int 类型
Box<double> doubleBox(3.14); // 显式指定 double 类型
cout << intBox.getValue() << endl; // 输出:10
cout << doubleBox.getValue() << endl; // 输出:3.14
return 0;
}
输出:
10
3.14
说明:
template <typename T = int>:为T类型指定了默认类型int。Box<> intBox(10);:如果没有指定类型,T默认是int。
3. 模板特化(Template Specialization)
模板特化是指为特定类型提供模板的特殊实现。当你希望对某些类型提供定制化的实现时,模板特化非常有用。
3.1 函数模板特化
#include <iostream>
using namespace std;
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 特化 max 函数模板为 char 类型
template <>
char max<char>(char a, char b) {
cout << "Specialized version for char!" << endl;
return (a > b) ? a : b;
}
int main() {
cout << max(3, 5) << endl; // 使用默认版本
cout << max('a', 'b') << endl; // 使用特化版本
return 0;
}
输出:
5
Specialized version for char!
b
说明:
template <> char max<char>(char a, char b):为char类型特化了max函数模板。
3.2 类模板特化
#include <iostream>
using namespace std;
// 定义一个类模板
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() { return value; }
};
// 类模板特化为 char 类型
template <>
class Box<char> {
private:
char value;
public:
Box(char v) : value(v) {}
char getValue() { return value; }
void display() { cout << "Character Box: " << value << endl; }
};
int main() {
Box<int> intBox(10);
Box<char> charBox('A');
cout << intBox.getValue() << endl; // 输出:10
charBox.display(); // 输出:Character Box: A
return 0;
}
输出:
10
Character Box: A
说明:
template <> class Box<char>:特化了Box类模板为char类型,提供了额外的display成员函数。
4. 总结
C++ 模板是一个非常强大且灵活的功能,能够实现高效的泛型编程。模板可以分为函数模板和类模板,它们使得代码能够适应不同的数据类型。通过模板特化,我们还可以为特定类型提供特殊的实现。使用模板可以显著提高代码的重用性和可维护性。