一:类模板的实现
实例:
#include <vector>
#include <stdexcept>
template <typename T> //类模板声明部分 同样可以使用class T为模板参数
class Stack {
private:
std::vector<T> elems;
public:
//Stack(); //构造函数
//Stack (Stack<T> const&); //拷贝构造函数
//Stack<T>& operator= (Stack<T> const&); //赋值运算符
void push(T const&);
void pop();
T top() const;
bool empty() const {
return elems.empty();
}
};
template <typename T>
void Stack<T>::push(T const& elem)
{
elems.push_back(elem);
}
template<typename T>
void Stack<T>::pop()
{
if (elems.empty())
{
throw std::out_of_range("Pop() empty stack");
}
elems.pop_back();
}
template <typename T>
T Stack<T>::top() const {
if (elems.empty())
{
throw std::out_of_range("top() empty stack");
}
return elems.back();
}
注:类的类型是Stack<T> ,类名是stack 指定类型,构造函数 析构函数 应该用Stack
二:类模板的使用
实例:
int main()
{
try
{
Stack<int> intStack;
Stack<std::string> stringStack;
//使用int栈
intStack.push(7);
std::cout << intStack.top() << std::endl;
//使用string栈
stringStack.push("hello");
std::cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (std::exception const& ex)
{
//...
}
}
注:只有在调用成员函数时才会产生实例化代码,可以节约空间和时间,而且对于使用了某些类型不支持操作的函数,不调用就可以。模板实参可以是任何类型,但是该类型必须提供被调用的所有操作。
特:stack<stack<int> > intStackStack; 两个>>中间必须要有空格 否则会被理解为operator>>
三:类模板的特化
目的:优化某种特定类型的实现,或者克服某种特定类型的不足,例如不支持某些操作等等。
特化一整个类模板,需要特化所有的成员函数
实例:
template<>
class Stack<std::string>
{
private:
std::deque<std::string> elems;
public:
void push(std::string const&);
void pop();
std::string top() const;
bool empty() const {
return elems.empty();
}
};
void Stack<std::string>::push(std::string const& elem)
{
elems.push_back(elem);
}
void Stack<std::string>::pop()
{
if (elems.empty())
{
throw std::out_of_range("stack<std::string>::pop(): empty stack");
}
elems.pop_back();
}
std::string Stack < std::string >::top() const {
if (elems.empty())
{
throw std::out_of_range("stack<std::string>::top(): empty stack");
}
return elems.back();
}
四:类模板的局部特化
template <typename T1, typename T2>
class MyClass {
};
//局部特化版本
template <typename T>
class MyClass<T, T> {
};
template <typename T>
class MyClass<T, int> {
};
template<typename T1, typename T2>
class MyClass<T1*, T2*> {
};
注意二义性问题。
五:缺省模板实参
template <typename T, typename CONT = std::vector<T> >
class Stack {
private:
CONT elems;
public:
void push(T const&);
void pop();
T top() const;
bool empty() const {
return elems.empty();
}
};
template <typename T, typename CONT>
void Stack<T, CONT>::push(T const& elem)
{
elems.push_back(elem);
}
template <typename T, typename CONT>
void Stack<T, CONT>::pop()
{
if (elems.empty())
{
throw std::out_of_range("Stack<>::pop(): empty stack");
}
elems.pop_back();
}
template <typename T, typename CONT>
void Stack<T, CONT>::top() const {
if (elems.empty()) {
throw std::out_of_range("Stack<>::top() : empty stack");
}
return elems.back();
}