C++进阶模板

Posted Huang_ZhenSheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++进阶模板相关的知识,希望对你有一定的参考价值。

目录

类模板 

模板的特化

函数模板特化:

类模板特化:

全特化:

偏特化/半特化

模板分离编译

=====>>> 分析

解决方案:

按需实例化 

模板小结


类模板 

//类模板
template<class T>
class Stack

public:
	Stack(int capacity = 4)
		:_a(new T[capacity])
		, _top(0)
		, _capacity(capacity)
	
	~Stack()
	
		delete[] _a;
		_a = nullptr;
		_top = _capacity = 0;
	
	//类里面声明,类外面定义?
	void Push(const T& x);
private:
	T* _a;
	int _top;
	int _capacity;
;

//在类外面定义
template<class T>
void Stack<T>::Push(const T& x)

     //

int main()

	//类模板的使用都是显示实例化
	Stack<TreeNode*>st1;
	Stack<int>st2;

注意:在类外面定义的时候,要加个模板的声明

普通类:类名就是类型

类模板:类名不是类型,类型是Stack<T>

模板不支持把声明写到.h,定义写到.cpp,这种声明和定义分开实现的方式,使用的时候会出现链接错误

模板的特化

针对某些类型进行特殊化处理

函数模板特化:

template<class T>
void Swap(T& a,T& b)

	T tmp = a;
	a = b;
	b = tmp;

int main()

	int x = 10;
	int y = 20;
	Swap(x,y);

	vector<int>v1 =  1, 2, 3, 4 ;
	vector<int>v2 =  10, 20, 30, 40 ;
	Swap(v1,v2);

	return 0;

 以上代码会导致三次深拷贝,代价太大

template<class T>
void Swap(T& a,T& b)

	T tmp = a;
	a = b;
	b = tmp;

//模板匹配原则,进行特殊化处理
void Swap(vector<int>& a, vector<int>& b)

	a.swap(b);

//函数的模板特化
template<>
void Swap<vector<int>>(vector<int>& a, vector<int>& b)

	a.swap(b);

int main()

	int x = 10;
	int y = 20;
	Swap(x,y);

	vector<int>v1 =  1, 2, 3, 4 ;
	vector<int>v2 =  10, 20, 30, 40 ;
	Swap(v1,v2);

	return 0;

类模板特化:

全特化:

template<class T1, class T2>
class Data

public:
	Data() 
	 
		cout << "Data<T1, T2>" << endl; 
	
private:
	T1 _d1;
	T2 _d2;
;
template<>
class Data<int, char>

public:
	Data() 
	 
		cout << "Data<int, char>" << endl; 
	
private:
	int _d1;
	char _d2;
;
void TestVector()

	Data<int, int> d1;
	Data<int, char> d2;

int main()

	TestVector();
	return 0;

偏特化/半特化

部分特化

template<class T1>
class Data<T1, char>

public:
	Data() 
	 
		cout << "Data<T1, char>" << endl; 
	
private:
;
void TestVector()

	Data<int, int> d1;
	Data<double, double> d2;
	Data<double, char> d3;
	Data<int, char> d4;

参数的更进一步限制:

template<class T1,class T2>
class Data<T1*, T2*>

public:
	Data() 
	 
		cout << "Data<T1*, T2*>" << endl; 
	
private:
;
template<class T1, class T2>
class Data<T1&, T2&>

public:
	Data()
	
		cout << "Data<T1&, T2&>" << endl;
	
private:
;
void TestVector()

	Data<int*, int*> d1;
	Data<double&, double&> d2;
	Data<double, char> d3;
	Data<int, char> d4;

模板分离编译

模板不支持分离编译

 以上调用 F 函数出现链接错误,而调用 Print 函数正常----why?

=====>>> 分析

由于不知道 T 的类型,实例化是在编译的时候做的事情,但是在生成链接之前都是独立的,到链接的时候合并的时候只剩下指令

解决方案:

方案1:显示指定实例化---不推荐,换个类型就又链接不上

方案2:

不分离编译,声明和定义或者直接定义在.h中

按需实例化 

push有语法问题,没有被检查出来,编译不报错,为什么??

原因:模板如果没有实例化,编译器不会去检查模板内部语法错误

 我们实例化了栈这个类,对类模板是按需实例化,调用了哪个成员函数就实例化谁

template<class T>
class Stack

public:
	Stack();
	~Stack();
	void Push(const T& x);
private:
	T* _a;
	int _top;
	int _capacity;
;
template<class T>
Stack<T>::Stack()

	_a = new T[10];
	_top = 0;
	_capacity = 10;

template<class T>
Stack<T>::~Stack()

	delete[] _a;
	_a = nullptr;

template<class T>
void Stack<T>::Push(const T & x)

	//代码有语法问题,为什么还能编译通过??
	_a[_top] = x
	++_top;

模板小结

以上是关于C++进阶模板的主要内容,如果未能解决你的问题,请参考以下文章

C++——模板进阶

C++模板进阶

C++模板进阶

C++模板进阶

[ C++ ] template 模板进阶 (特化,分离编译)

C++模板进阶