在C++中,函数模板和类模板是实现泛型编程的工具,它们允许在不指定具体数据类型的情况下定义函数和类。这样可以提高代码的重用性和灵活性。以下是对这两个概念的详细讲解。
函数模板(Function Template)
- 定义:
函数模板是一种能够处理不同数据类型的函数框架。通过使用模板参数,函数可以针对任意类型的输入进行操作。 - 语法:
函数模板的基本语法如下:
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
- 使用:
使用函数模板时,C++会根据调用中的参数类型自动推导出模板参数。
int main() {
std::cout << max(10, 20) << std::endl; // 输出 20
std::cout << max(5.5, 3.2) << std::endl; // 输出 5.5
std::cout << max('a', 'b') << std::endl; // 输出 'b'
return 0;
}
- 特性:
- 类型推导:在函数调用时自动推导类型。
- 多个类型参数:可以定义多个模板参数,例如:
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
- 默认模板参数:可以使用默认参数,可以在声明时提供默认数据类型。
template <typename T = int>
void display(T value) {
std::cout << value << std::endl;
}
类模板(Class Template)
- 定义:
类模板是一种允许创建与数据类型无关的类的方式。可以用模板参数定义成员变量和成员函数的类型。 - 语法:
类模板的基本语法如下:
template <typename T>
class Pair {
private:
T first, second;
public:
Pair(T a, T b) : first(a), second(b) {}
T getFirst() { return first; }
T getSecond() { return second; }
};
- 使用:
定义类模板后,可以创建其实例,例如:
int main() {
Pair<int> intPair(1, 2);
std::cout << intPair.getFirst() << ", " << intPair.getSecond() << std::endl; // 输出 1, 2
Pair<double> doublePair(1.1, 2.2);
std::cout << doublePair.getFirst() << ", " << doublePair.getSecond() << std::endl; // 输出 1.1, 2.2
Pair<std::string> stringPair("Hello", "World");
std::cout << stringPair.getFirst() << ", " << stringPair.getSecond() << std::endl; // 输出 Hello, World
return 0;
}
- 特性:
- 模板参数可以是任意类型,包括类、结构体、内置类型等。
- 可以有多个模板参数,形如:
template <typename T, typename U>
class MyClass { /*...*/ };
- 支持部分特化与完全特化。例如:
template <typename T>
class MyClass<T*> { /* ... */ }; // 指针类型的特化
示例综合
以下是结合函数模板和类模板的完整示例:
#include <iostream>
#include <string>
// 函数模板
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 类模板
template <typename T>
class Pair {
private:
T first, second;
public:
Pair(T a, T b) : first(a), second(b) {}
T getFirst() const { return first; }
T getSecond() const { return second; }
};
int main() {
// 使用函数模板
std::cout << "Max of 10 and 20: " << max(10, 20) << std::endl; // 输出 20
std::cout << "Max of 5.5 and 3.2: " << max(5.5, 3.2) << std::endl; // 输出 5.5
// 使用类模板
Pair<int> intPair(1, 2);
std::cout << "Pair<int>: " << intPair.getFirst() << ", " << intPair.getSecond() << std::endl; // 输出 1, 2
Pair<std::string> stringPair("Hello", "World");
std::cout << "Pair<string>: " << stringPair.getFirst() << ", " << stringPair.getSecond() << std::endl; // 输出 Hello, World
return 0;
}
总结
- 函数模板允许你定义一个可以接收任意类型的函数,并在调用时自动进行类型推导。
- 类模板允许你定义一个可以处理任意类型的类,适用于不同类型的实例化。
- 使用模板编程可以显著提高代码的重用性,并减少代码重复