C++编程思想:模板

模板的特性1:需要遵守约定

模板将类型以一个标识符替代,想要使用模板就需要遵守模板对这个标识符的要求,比如对标识符有什么成员变量以及成员函数。

#include <iostream>
#include <vector>
using namespace::std;

//*****************这是一个模板类的实现,展示模板的特性之一:约定性*******************************
template<class T> class X
{
public:
	typename T::id i; //约定类型T中有id这个类型,并且创建一个id类型的变量,typename是关键字,用typename 告诉编译器T::id是一个类型标识符
public:
	void f() {
		i.g(); //约定i中有g()这个函数
	}
};

class Y
{
public:
	class id
	{
	public:
		void g() {
			cout << "this is the Y::id object function g()" << endl;
		}
	};
};


/*
int main() {
	X<Y> xy;
	xy.f();
}
*/

在这里插入图片描述

模板类型的模板参数

//********************************这是一个模板类型的模板参数案例****************************
template <class T, template <class> class Seq> //T是一个类型,Seq是一个模板类型,这个模板类型有一个参数(无需写出参数名)
class Container
{
public:
	Seq<T> seq; //Seq模板类型中的类型参数是T
public:
	void printSeq() {
		cout << "the size of seq : " << seq.size() << endl;
	}
	void push_back(T t)
	{
		seq.push_back(t);
	}
};
template<class T>  class Vec
{
public:
	vector<T> vec;
public:
	void push_back(T t)
	{
		vec.push_back(t);
	}

	size_t size() {
		return vec.size();
	}
};

/*
int main()
{
	Container<int, Vec> cv;
	cv.push_back(1);
	cv.push_back(2);
	cv.printSeq();
	
}
*/

在这里插入图片描述

函数成员模板和类成员模板

//***********************成员函数中的模板:分为函数成员模板和类成员模板*********************************
template <class T> class com
{
public:
	T t;
	com(const T& tt) :t(tt){
		std::cout << "t : " << t << endl;
	}
	template <class U> com(const com<U>& u) : t(u.t) //成员函数模板
	{
		std::cout << "u : " << t << endl;
	}
};

template <class T> class outer
{
public:

	template<class R> class iner //成员函数类
	{
	public:
		//template<class T>  template<class R>
		void f()
		{
			std::cout << "out " << typeid(T).name() << endl;
			std::cout << "inner " << typeid(R).name() << endl;
			std::cout << "this " << typeid(*this).name() << endl;
		}
	};
};

/*
int main() {
	com<float> a(1);
	com<double> b(a);
	outer<float>::iner<int> ou;
	ou.f();
	outer<float>::iner<int> oc(ou); //这里会调用拷贝构造函数
}

*/

在这里插入图片描述

模板特化以及模板重载

在实例化模板时,优先考虑特化程度高的模板,比如有指针修饰符修饰的模板或者直接特化的模板,若特化程度高的模板可以匹配就使用特化程度高的模板,当然匹配度是更重要的指标。

//*****************模板特化以及模板重载************************************
#include<stack>
template <class StackType>
void emptyTheStack(StackType& stk)
{
	cout << "this is stackType" << endl;
}

template <class StackType>
void emptyTheStack(stack<StackType*> & stk) //经过指针特化的模板,当实例化为参数为指针时优先调用此模板
{
	cout << "this is stack<StackType*>" << endl;
}

template<>
void emptyTheStack(float& stk) //直接float 类型,显示特化
{
	cout << "this is float& stk" << endl;
}

void emptyTheStack(int stk) //重载模板函数
{
	cout << "this is int stk" << endl;
}

int main()
{
	double a = 1;
	emptyTheStack(a); //调用第一个模板

	float b = 1;
	emptyTheStack(b);//调用第三个模板

	stack<float*> c;
	emptyTheStack(c); //调用第二个模板

	int d = 1;
	emptyTheStack(d);//调用最后一个重载函数
}

在这里插入图片描述

模板中的符号解析

如果符号定义涉及到未确定类型,在编译的第一阶段只会在已经定义的符号表中查找该符号,不会到不确定类型中查找该符号。

//********************************关联不确定类型标识符的编译*************************
#include<algorithm>
#include<typeinfo>
using std::cout;
using std::endl;

void g() { cout << "global g()" << endl; } //全局定义

template <class T> class YY
{
public :
	void g()
	{
		cout << "Y<" << typeid(T).name() << ">::g()" << endl;
	}
	void h()
	{
		cout << "Y<" << typeid(T).name() << ">::h()" << endl;
	}
	typedef int E; //局部定义
};

typedef double E; //全局定义

//一个全局定义的模板函数
template<class T> void swap(T& t1, T& t2)
{
	cout << "global swap" << endl;
	T temp = t1;
	t1 = t2;
	t2 = temp;
}

template<class T> class XX :public YY<T>
{
public:
	E f() //E的返回类型是double
	{
		g(); //这个会编译成全局函数,而不是YY中的函数定义体,因为YY中的函数定义体是关联未定类型的,不会优先编译
		this->h();//这是YY中的
		T t1 = T(0);
		T t2 = T(1);
		cout << "t1: " << t1 << endl;
		cout << "t2: " << t2 << endl;
		swap(t1, t2);
		std::swap(t1, t2);
		cout << "E type: " << typeid(E).name() << endl;
		return E(t2);
	}
};
int main()
{
	XX<int> x;
	cout << x.f() << endl;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值