类模板的特化与局部特化

//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>

局部特化:为了在某种情况下,我们希望调用的是局部特化版本的函数,而掩盖泛化版本的不足时,
就写一个特定的局部特化版本函数。

*/

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38158479/article/details/114183008