一个类模板可以具有一个或者多个模板参数。当这组模板参数被设定为一组具体类型时,实例化后的类就能够处理这组具体类型的数据。模板参数可以被设定为任意类型,使得这个类模板可以处理任意类型的数据,这是泛型编程思想所要达到的目标。然而,在某些场合下,当模板参数被设定为某些特定类型时,我们希望实例化后的类具有特定的行为,这就需要使用类模板特化技术。
//mystack.h
#ifndef MYSTACK_H
#define MYSTACK_H
#include <iostream>
#include <vector>
#include <deque>
#include <QDebug>
/// 主类模板
template <typename T>
class MyStack
{
public:
MyStack<T>(){
qDebug() << "class MyStack<T>";
}
private:
std::vector<T> elems;
public:
void push(T const& elem){
elems.push_back(elem);
}
void pop(){
if(elems.empty()) return;
elems.pop_back();
}
T top() const{
if(elems.empty()) return;
return elems.back();
}
};
/// 特化类模板
template <>
class MyStack<int>
{
public:
MyStack<int>(){
qDebug() << "class MyStack<int>";
}
private:
std::vector<int> elems;
public:
void push(int const& elem){
qDebug() << "class MyStack<int>" ;
}
};
#endif // MYSTACK_H
// main.cpp
#include <QCoreApplication>
#include "mystack.h"
#include <QString>
#include <QDebug>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 使用特化类模板
MyStack<int> istack;
for (int var = 0; var < 100; ++var) {
istack.push(1);
qDebug() << var << endl;
}
// 使用主类模板
MyStack<QString> strStack;
for (int var = 0; var < 100; ++var) {
strStack.push(QString("string %1").arg(var));
}
return a.exec();
}
从最终的打印结果看以看到,在使用特化模板类 实例化对象时,可以做一些与众不同的处理;而未作特化的类型,在使用主类模板实例化对象后,将会具有完全相同的操作(相同的成员函数的调用)。
可以说类模板特化,是泛型之中特别的亮点之一。接下来还要多总结,灵活使用。