微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【C++】 模板进阶


前言

模板参数分类类型形参与非类型形参。 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。

一、模板参数

非类型模板参数的引用,解决了我们部分问题,

  1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
  2. 非类型的模板参数必须在编译期就能确认结果。
namespace ljh
{
 // 定义一个模板类型的静态数组
	 template<class T =int, size_t N = 10>
	 class array
	 {
	 private:
	 T _array[N];
	 size_t _size;
	 }
 }
 int main()
 {
 	ljh::array<int,100> s1;
 	ljh::array<int,70> s2;
 }

类似上面这种情况,我们两个栈需要开辟不同的空间的时候,如果没有这个模板参数的话我们就需要写两个类。
若是全缺省的类,我们调用也需要 ljh::array<> s1;



模板的特化

什么时候需要用到呢?
当我们实现一个Is_empty的函数用来判断两个值是否相同。但是由于不同类型可能比较方式有所差异,我们这个时候可以使用特化,或者利用模板的匹配原则。

template<class T>
bool Is_empty(T left,T right)
{
	cout << "hah" << endl;
	return left == right;
}
template<>//特化
bool Is_empty<char*>(char* left,char* right)
{
	return strcmp(left,right) == 0;
}
//模板的匹配原则
bool Is_empty(char* left,char* right)
{
	return strcmp(left,right) == 0;
}

int main()
{
	int left = 0;
	int right = 0;
	//cout << Is_empty(left, right)<<endl;
	char str1[] = "woaini";
	char str2[] = "woaini";
	cout<<typeid(str1).name()<<endl;
	cout << Is_empty(str1, str2) << endl;

	
	return 0;
}

注意这里的str1,str2本质是数组名,在传参的时候,存在类型转换,所以我们要在上面的传参过程中如果讲模板函数改成下面的const T&,则对于特化版本会存在问题。

template<class T>
bool Is_empty(const T& left,const T& right)//error!
{
	cout << "hah" << endl;
	return left == right;
}
template<>
bool Is_empty<char*>(char* left,char* right)
{
	return strcmp(left,right) == 0;
}


二、分离编译

1.引入库

解决方案1:显式指定实例化。

在这里插入图片描述


在这里插入图片描述

解决方案2:不分离编译。声明和定义在一个.h文件当中。因为这样子在编译的时候他的函数的地址就已经确认了。


总结

模板进阶就到这里!!

原文地址:https://www.jb51.cc/wenti/3280712.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐