模板与泛型编程

定义模板

template<typename T,typename B,class C>  //typename和class的作用一样
//这里面的T,B,C都是模板类型参数

函数模板

template <typename T>
T compare(const T &a,const T &b)  //模板类型可以看作一般的内置类型来使用
{
if (a<b) return 1;
if(a>b) return -1;
}

非类型模板参数
模板中出了可以定义类型参数,也可以定义非类型参数,例如

template<unsigned N,unsigned M>
compare(const char (&p1)[N],const char (&p2)[M])
{
return strcmp(p1,p2);
}

当模板被实例化时,非类型模板参数将会被一个用户提供的或编译器推断出的值所代替,这些值必须是常量表达式,从而允许编译器在编译时实例化模板。即:绑定到非类型模板参数的实参必须是常量表达式。

模板编译
模板只有在实例化时,编译器才会生成代码,为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。因此,函数模板和类模板的成员函数的定义通常放在头文件中。

类模板
类模板是用来生成类的蓝图的 不同与模板函数 编译器不能为类模板推断模板参数类型 我们必须在模板名后的尖括号中提供额外信息,用来替代模板参数

//定义类模板
template<typename T> class Blob{
public:
	typedef T value_type;  //类的类型成员
	typedef typename std::vector<T>::size_type size_type;
	Blob();
	Blob(std::initializer_list<T> il); //构造函数
	size_type size() const {return data->size();}
	bool empty() const {return data->empty();}
	void push_back(const T& t){data->push_back(t);}
	T& operator[] (size_type i); // 元素访问
	T& back();
private:
	std::shared_ptr<std:vector<T>> data;
	void check(size_type i,const std::string &msg) const;
//实例化类模板
Blob<int> ia;
Blob<int> ia2={0,1,2,3,4} //每次实例化类模板时 编译器会重新Blob模板 每个实例都会形成一个独立的类 他们之间没有任何关联 

注意:类模板的名字不是一个类型名,是模板

类模板的成员函数
类模板的成员函数本身是一个普通函数 但是不同的类模板实例都会有自己版本的成员函数 所以 模板成员函数具有和模板相同的模板参数 定义在外部的成员函数前面要加上template关键字 后面接类模板参数列表
例如:

template<typename T> ret-type Blot<T>::member-name(param-list)
template<typename T>
void Blob<T>::check(size_type i,const std::string &msg) const 
{
	if(i>=data->size())
		throw std::out_of_range(msg);
}

template<typename T> T& Blot<T>::back()
{
	check(0,"back on empty Blob");
	return data->back();
}

template<typename T>
T& Blob<T>::operator[](size_type i)
{
	check(i,"subscript out of range");
	return (*data)[i];
}

template<typename T>
void Blob<T>::pop_back()
{
	check(0,"pop_back on empty Blob");
	data->pop_back();
}
//构造函数的定义
template <typename T>
Blob<T>::Blot():data(std::make_shared<std::vector<T>>()) {}
template<T>
Blob<T>::Blob(std::initializer_list<T> il):data(std::make_shared<std::vector<T>>(il)){}

一个类模板成员函数只有在用到它是时才进行实例化,在类模板自己的作用于中,我们可以直接使用模板名而不用提供实参。
例如:

template <typename T> class BlobPtr
{
	BlobPtr& operator++();
	BlobPtr& operator--(); // 这里没用BlobPtr<T>&
}

成员模板
本身是模板的成员函数,称为成员模板

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值