//main.c
#include "pch.h"
#include <iostream>
#include "stack1.h"
#include<string>
using namespace std;
int main()
{
//
int i = 0, ret = 0;
_space1::stack<int> s;//实例化
for (i = 0; i < 10; i++)
{
s.push(i);
}
ret = s.top();
cout << "栈顶元素为: "<<ret << endl;
s.pop();
ret = s.top();
cout << "栈顶元素为: " << ret << endl;
if (s.empty())
{
cout << "没有元素,栈为空" << endl;
}
cout << endl;
//类模板特化
_space1::stack<string> str;//实例化
string str1 = "aa";
str.push(str1);
cout << str.top() << endl;
str.pop();
if (str.empty())
{
cout << "特化版本类型stack为空" << endl;
}
cout << endl;
//类模板泛化
myclass<int, float> my1;
myclass<float, float> my2;
myclass<float, int> my3;
return 0;
}
//stack1.h
#include "pch.h"
#include<vector>
#include<deque>
using namespace std;
namespace _space1
{
template<typename T>
class stack
{
private:
std::vector<T> elems;
public:
void push(T const&);
void pop();
T top()const;
bool empty() const;
public:
stack();
stack(stack<T> const&);
stack<T> operator=(stack<T> const&);
};
template<typename T>
_space1::stack<T>::stack()
{
cout << "调用的是泛化版本的类模板" << endl;
cout << "stack的构造函数" << endl;
}
template<typename T>
_space1::stack<T>::stack(stack<T> const&)
{
}
template<typename T>
stack<T> stack<T>::operator=(stack<T> const&)
{
}
template<typename T>
bool stack<T>::empty() const
{
//cout << "调用的是泛化版本的类模板" << endl;
return elems.empty();
}
template<typename T>
void stack<T>::push(T const& elem)
{
elems.push_back(elem);
}
template<typename T>
void stack<T>::pop()
{
//cout << "调用的是泛化版本的类模板" << endl;
if (stack<T>::empty())
{
cout << "元素为空,无法出栈" << endl;
}
elems.pop_back();
}
template<typename T>
T stack<T>::top() const
{
//cout << "调用的是泛化版本的类模板" << endl;
if (stack<T>::empty())
{
cout << "元素为空,无法获取栈顶元素" << endl;
}
return elems.back();
}
/*
1:类模板的声明:
template<typename T>
class stack
{
.....
};
也可以,
template<class T>
class stack
{
.....
};
2:类外定义成员函数时,需要加上template<typename T>
且,类的类型为stack<T>,
当然,类名还是stack,所以在写构造函数或者赋值运算符时,要注意区分。
*/
//二:类模板的特化与局部特化
template<>
class stack<std::string>
{
private:
std::deque<std::string> elems; //类的特化版本可以与泛化版本完全不同
public:
stack()
{
cout << "调用的是特化版本的类模板" << endl;
}
public:
void push(std::string const&);
void pop();
std::string top()const;
bool empty() const;
};
bool stack<std::string>::empty() const
{
//cout << "调用的是特化版本的类模板" << endl;
return elems.empty();
}
//特化版本成员函数类外定义
void stack<std::string>::push(std::string const& elem)
{
//cout << "调用的是特化版本的类模板" << endl;
elems.push_back(elem);
}
void stack<std::string>::pop()
{
//cout << "调用的是特化版本的类模板" << endl;
if (stack<std::string>::empty())
{
cout << "元素为空,无法出栈" << endl;
}
elems.pop_back();
}
std::string stack<std::string>::top()const
{
//cout << "调用的是特化版本的类模板" << endl;
if (stack<std::string>::empty())
{
cout << "元素为空,无法获取栈顶元素" << endl;
}
return elems.back();
}
/*
1:特化版本基于泛化版本存在
2:特化版本是为了克服泛化版本中存在的某种不足,而做出的改进。
3:特化版本以template<>开头,同时,没个成员函数也需要进行特化,
如果只是特化某部分成员函数,那么就不算类的特化。
4:特化版本的成员函数在类外定义时,只需写成和普通成员函数一样即可。
5:特化版本可以与泛化版本完全不同
*/
}
//泛化版本
template<typename T,typename U>
class myclass
{
public:
myclass()
{
cout << "调用泛化版本" << endl;
}
void sum();
private:
T i;
U j;
};
template<typename T, typename U>
void myclass<T, U>::sum()
{
cout << "i+j = " << i + j << endl;
}
//局部特化版本
template<typename T>
class myclass<T,T>
{
public:
myclass()
{
cout << "调用局部特化myclass<T,T>版本" << endl;
}
void sum();
private:
T i;
T j;
};
template<typename T>
void myclass<T,T>::sum()
{
cout << "i+j = " << i + j << endl;
}
//局部特化版本
template<typename T>
class myclass<T, int>
{
public:
myclass()
{
cout << "调用局部特化myclass<T, int>版本" << endl;
}
void sum();
private:
T i;
int j;
};
template<typename T>
void myclass<T, int>::sum()
{
cout << "i+j = " << i + j << endl;
}
/*
如果有多个局部特化版本同等程度的匹配某个声明,那么就称该声明具有二义性,
例如myclass<int,int> my;
这会同时匹配上, myclass<T, int>和 myclass<T,T>
局部特化:为了在某种情况下,我们希望调用的是局部特化版本的函数,而掩盖泛化版本的不足时,
就写一个特定的局部特化版本函数。
*/