C++(模板)
在C++中,模板是泛型编程的重要工具,用于编写通用和可重用的代码。模板主要有两种类型:函数模板和类模板。
1. 函数模板(Function Templates)
函数模板允许你定义一个函数,其操作可以应用于不同的数据类型。它们可以在编译时生成多个版本的函数,以适应不同的数据类型。
1.1 基本语法:
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
这里,template <typename T> 定义了一个模板,其中 T 是一个类型参数。max 函数可以接受任意类型的参数,只要这两个参数的类型相同。
1.2 使用示例:
int main() {
cout << max(10, 20) << endl; // 使用int
cout << max(10.5, 20.5) << endl; // 使用double
return 0;
}
C++编译器根据调用 max 函数时的参数类型自动生成相应的函数版本。
2. 类模板(Class Templates)
类模板允许你定义一个类,其数据成员和成员函数可以依赖于模板参数。这使得类可以处理不同的数据类型。
2.1 基本语法:
template <typename T>
class Stack {
private:
vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
T pop() {
if (elements.empty()) throw out_of_range("Stack<>::pop(): empty stack");
T elem = elements.back();
elements.pop_back();
return elem;
}
bool empty() const {
return elements.empty();
}
};
这里,template <typename T> 定义了一个类模板,T 是一个类型参数。Stack 类可以处理任意类型的数据。
这段C++代码定义了一个模板类
Stack,实现了一个泛型栈的数据结构。让我们逐行解析这段代码:1. 模板定义
template <typename T> class Stack {
template <typename T>: 这行声明了一个模板类。T是模板参数,表示栈中存储的元素类型。使用typename或class都可以,typename是更常用的习惯。2. 私有成员
private: vector<T> elements;
private: 访问控制标记,表示下面的成员只能在类的内部访问。vector<T> elements;: 这是一个vector容器,用于存储栈中的元素。vector是一个标准库容器,T是其元素类型,说明Stack类可以存储任何类型的元素。3. 公有成员函数
push函数public: void push(const T& element) { elements.push_back(element); }
void push(const T& element): 这是一个公有成员函数,用于将元素element压入栈中。参数const T& element是T类型的常量引用,避免了拷贝操作,提高了效率。elements.push_back(element);: 将元素添加到vector的末尾,这样实现了栈的“入栈”操作。
pop函数T pop() { if (elements.empty()) throw out_of_range("Stack<>::pop(): empty stack"); T elem = elements.back(); elements.pop_back(); return elem; }
T pop(): 这是一个公有成员函数,用于从栈中移除并返回栈顶元素。if (elements.empty()) throw out_of_range("Stack<>::pop(): empty stack");: 如果栈为空,抛出out_of_range异常,避免在空栈上执行pop操作。T elem = elements.back();: 获取栈顶的元素(即vector的最后一个元素)。elements.pop_back();: 从vector中移除栈顶元素,执行“出栈”操作。return elem;: 返回被移除的元素。
empty函数bool empty() const { return elements.empty(); }
bool empty() const: 这是一个公有成员函数,用于检查栈是否为空。const关键字表明此函数不会修改类的成员数据。return elements.empty();:empty()是vector的成员函数,返回true如果vector为空,false如果vector里有元素。总结
- 数据成员:
elements是一个vector容器,存储栈中的元素。- 成员函数:
push(const T& element): 将元素压入栈中。pop(): 移除并返回栈顶的元素,若栈为空则抛出异常。empty() const: 检查栈是否为空。这个
Stack类模板允许你创建类型安全的栈,适用于任何数据类型。由于它是一个模板类,你可以用不同的类型实例化Stack类,如Stack<int>、Stack<double>等。
2.2 使用示例:
int main() {
Stack<int> intStack;
intStack.push(1);
intStack.push(2);
cout << intStack.pop() << endl; // 输出 2
Stack<string> stringStack;
stringStack.push("hello");
stringStack.push("world");
cout << stringStack.pop() << endl; // 输出 "world"
return 0;
}
使用
Stack模板类来创建和操作两个Stack对象:一个用于存储int类型的元素,另一个用于存储string类型的元素。1. 创建
int类型的栈对象Stack<int> intStack;
Stack<int>: 这里使用Stack类模板创建一个类型为int的栈。intStack是这个栈的实例,专门存储int类型的数据。2. 入栈操作
intStack.push(1); intStack.push(2);
intStack.push(1);: 将整数1压入intStack中。此时栈的状态是[1]。intStack.push(2);: 将整数2压入栈中。此时栈的状态是[1, 2],2是栈顶元素。3. 出栈操作及输出
cout << intStack.pop() << endl; // 输出 2
intStack.pop(): 从intStack中移除栈顶的元素并返回它。此时栈顶元素2被移除,栈的状态变为[1]。返回的值2被传递到cout中输出。cout << intStack.pop() << endl;: 输出2,并换行。4. 创建
string类型的栈对象Stack<string> stringStack;
Stack<string>: 这里使用Stack类模板创建一个类型为string的栈。stringStack是这个栈的实例,专门存储string类型的数据。5. 入栈操作
stringStack.push("hello"); stringStack.push("world");
stringStack.push("hello");: 将字符串"hello"压入stringStack中。此时栈的状态是["hello"]。stringStack.push("world");: 将字符串"world"压入栈中。此时栈的状态是["hello", "world"],"world"是栈顶元素。6. 出栈操作及输出
cout << stringStack.pop() << endl; // 输出 "world"
stringStack.pop(): 从stringStack中移除栈顶的元素并返回它。此时栈顶元素"world"被移除,栈的状态变为["hello"]。返回的值"world"被传递到cout中输出。cout << stringStack.pop() << endl;: 输出"world",并换行。7. 结束程序
return 0;
return 0;: 结束main函数并返回0,表示程序成功结束。总结
这段代码展示了如何使用
Stack类模板来操作不同类型的栈对象:
- 创建了一个
int类型的栈intStack,进行了元素的入栈和出栈操作,并输出了出栈的结果。- 创建了一个
string类型的栈stringStack,进行了元素的入栈和出栈操作,并输出了出栈的结果。
Stack类模板的使用使得栈可以存储不同类型的数据,并且所有操作都是类型安全的。
3. 模板的特性
-
模板特化(Template Specialization):
-
全特化:为特定类型提供特定实现。
template <> class Stack<bool> { // 特化版本的实现 }; -
偏特化:为模板参数的某些组合提供特定实现。
template <typename T> class Pair<T, T> { // 特化版本的实现 };
-
-
非类型模板参数:
模板参数不仅可以是类型,也可以是常量值。template <int size> class Array { int arr[size]; }; -
模板递归:
可以在模板中进行递归定义,用于编写复杂的编译时计算。
模板机制提供了极大的灵活性和重用性,是C++语言强大的特性之一。

浙公网安备 33010602011771号