C++之模板
函数模板
在C++中, 模板被用于设计可重用的软件, 模板提供了将通用数据类型作为参数的能力.
比如有时, 在求一个最大值时, 不得不因为不同的数据类型而写许多除了数据类型外完全一致的代码:
int maxValue(int val1, int val2){
return val1>val2?val1:val2;
}
double maxValue(double val1, double val2){
return val1>val2?val1:val2;
}
char maxValue(char val1, char val2){
return val1>val2?val1:val2;
}
string maxValue(string val1, string val2){
return val1>val2?val1:val2;
}
当然在这个具体的例子中, 字符串的比较时二者地址的比较, 而非数组内容的比较.
它们几乎完全一样. 模板能使这个函数应用于所有的数据类型.
template<typename T>
T maxValue(T val1, T val2){
return val1>val2?val1:val2;
}
模板的定义必须用关键字template
开始, 后面跟一个参数列表, 每个参数前面必须跟关键字typename
或者class
. 我个人更喜欢使用typename
, 因为class
具有一定的歧义性. 如果要有多个参数, 所有参数都可以放在尖括号内, 例如template T<typename p1, typename p2, typename p3>
.
模板类
模板类能实现具有通用类型的类. 例如实现一个通用类型的栈. 在类声明前也要加上模板前缀, 因为模板类的函数也是模板函数, 所以在函数头前也需要加前缀. 下面是一个简单的栈的实现:
# include<iostream>
template <typename T>
class Stack{
public:
Stack();
bool empty() const;
T peek() const;
void push(T val);
T pop();
int getSize() const;
private:
T elements[100];
int size;
};
// 下面分离实现栈的函数
// 注意要声明函数作用域, 并且要附带参数类型
// 即Stack<T>::
template<typename T>
Stack<T>::Stack(){
this->size = 0;
}
template<typename T>
bool Stack<T>::empty(){
return this->size == 0;
}
template<typename T>
T Stack<T>::peek() const{
return this->elements[size - 1];
}
template<typename T>
void Stack<T>::push(T val){
this->elements[size++] = val;
}
template<typename T>
T Stack<T>::pop(){
return this->elements[—size];
}
template<typename T>
int Stack<T>::getSize() const{
return this->size;
}
模板参数也可以像函数参数一样提供一个缺省数据类型template <typename T = int>
. 也可以使用非类型参数, 例如:
template <typename T, int capacity>
class Stack{
// ...
private:
T elements[capacity];
int size;
};
如果敲入Stack<string, 500> stack;
就声明了一个最大容量为500的字符串栈.Vector
就是用模板实现的类, 它比数组更加灵活. 详情可以看STL那篇.
例如vector<vector<int> >
声明了一个二维向量. 中间最好要加个空格, 否则有些编译器会报错.