模板与泛型编程—定义一个模板

定义模板

如果我们需要反复用到一些函数,这些函数仅仅只是参数类型不同。他们定义的函数体完全一样,这时候我们就希望有一个函数模板。放入不同的模具就能生成不同的函数,以此来实现我们想要的功能。假如我们没有这些模板我们会大量定义如下的重载函数:

int compare(const string &v1,const string &v2)
{
	if(v1 < v2) return -1;
	if(v2 < v1) retrun 1;
	return 0;
}

int compare(const double &v1,const double &v2)
{
	if(v1 < v2) return -1;
	if(v2 < v1) retrun 1;
	return 0;
}
	

函数模板

现在我们来定义一个函数模板:

template <typename T>
int compare(const T &v1,const T &v2)
{
  	if(v1 < v2) return -1;
  	if(v2 < v1) return 1;
  	return 0;
}

看上去很简单嘛,不是吗?这里用到了一个关键字template,后面跟着模板参数列表

实例化函数模板
有了函数模板编译器是如何替我们选择模具呢?当然是传入的实参来告诉编译器用那个模具。实际上当编译器推断出模板参数是什么类型时, 他会用模板函数来实例出一个我们将要用的函数
模板类型参数
类型参数可以看作是类型说明符。例如:
template <typename T> T foo(T* p)
{
	T tmp = *p;
	return tmp;
}
//  有一点需要注意如果有多个不同的类型参数必须都标记出来

template <typename T, class U> calc (const T& ,const U&); (typenameclass 没有区别)
非类型模板参数
有时候我们需要模板非类型参数是一个常量值,这就需要定义一个 非类型参数。那么什么情况我们需要定义一个非类型参数?当我们需要编写一个compare版本处理字符串字面常量。这种字面常量是const char 的数组。由于我们希望能比较不同长度的字符串字面常量。所以我们将自己的参数定义为数组的引用。N,M表示数组的长度。
template <unsigned N,unsigned M> compare(char (&p1)[N],char (&p2)[M])
{
	return strcmp(p1,p2);
}

compare("hi","hello");
inline 和 constexpr 的函数模板
这里需要说明一下函数模板也可以被声明为inline 或 constexpr 的,和非模板函数一样。inline 或 constexpr 说明符放在函数返回类型值之前:
template <typename T> inline T min(const T&,const T&);

类模板

定义一个类模板
举一个例子:
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);
	}

	void push_back(T&& t)
	{
		data->push_back(std::move(t));
	}

	void pop_back();

	T& back();
	T& opertor[](size_type i);
private:
	std::shared_ptr<std::vector<T>> data;
	void check(size_type i, const std::string& msg) const;
};

定义一个模板编译器并不能推断出模板参数类型,必须由我们自己在模板类名后面的尖括号内添加额外的信息。

类模板的成员函数
类模板的成员函数和其他类相同既可以定义在类模板内部,也可以定义在类模板外部。定义在外部时需要加关键字 template。举个例子:
template<typename T>
ret-type Blob<T>::member-name(parm-list)

模板参数

成员模板

控制实例化

效率与灵活性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值