如何建设音乐网站,天津做网站找哪家公司,电商一共有什么平台,广州从化发布目录 一、模板使用时的一个小注意点二、非类型模板参数三、类模板的特化3.1函数模板的特化3.2类模板的特化3.2.1全特化3.2.2偏特化 四、模板的分离编译4.1模板不支持分离编译4.2模板分离编译报错的分析4.2解决方案 五、模板的总结 一、模板使用时的一个小注意点
在使用模板时在有些场景下需要加上typename来告诉编译器这里是类型否则会编译不通过。如我想写一个不只是针对vector类型打印数据该怎么改写上面的代码呢
#includeiostream
using namespace std;#includevectorvoid Print(const vectorint v)
{vectorint::const_iterator it v.begin();while (it ! v.end()){cout *it ;}coutendl;
}
int main()
{vectorint v;v.push_back(10);v.push_back(20);v.push_back(30);v.push_back(40);v.push_back(50);Print(v);return 0;
}首先对于泛型编程的思想一般都会考虑到用模板所以一般我们都会这么改写代码。如
#includeiostream
using namespace std;#includevector
templateclass Container
void Print(const Container v)
{Container::const_iterator it v.begin();while (it ! v.end()){cout *it ;it;}coutendl;
}
int main()
{vectorint v;v.push_back(10);v.push_back(20);v.push_back(30);v.push_back(40);v.push_back(50);Print(v);return 0;
}但是呢这种代码连编译都通过不了。如 为什呢 其实是编译器不知道Container::const_iterator这个是类型还是对象 需要在前面加上typename告诉编译器这个是类型等模板实例化后再去找。如
二、非类型模板参数
假设有这样一个场景我需要创建2个静态的顺序表。一个顺序表的容量是10个另一个是1000个该怎么玩呢按照常规的方法肯定是玩不了的这时就需要非类型模板参数了。可以这么玩。如
namespace Ting
{templateclass T,size_t Nclass vector{private:T _arr[N];size_t capapcity;};
}int main()
{Ting::vectorint, 10 v1;Ting::vectorint, 1000 v2;return 0;
}注意
浮点数、类对象以及字符串是不允许作为非类型模板参数的。非类型的模板参数必须在编译期就能确认结果且不能被修改。
三、类模板的特化
3.1函数模板的特化
直接先看代码见一见猪跑。
//函数模板的特化
templateclass T
bool Less(T x, T y)
{return x y;
}//对函数模板进行特化
template
bool Lessint*(int* x, int* y)
{return *x *y;
}
int main()
{int a 2, b 1;cout Less(a, b) endl;return 0;
}乍一看是不是感觉函数模板特化有点与函数重载类似感觉这个没啥用但是这个是错觉。如
//函数模板的特化
templateclass T
bool Less(T x, T y)
{return x y;
}//对函数模板进行特化
templateclass T
bool Less(T* x, T* y)
{return *x *y;
}
int main()
{int a 2, b 1;double c 2.1, d 2.2;cout Less(a, b) endl;cout Less(c, d) endl;return 0;
}这种写法比函数重载要方便多了。 函数模板的特化步骤
必须要先有一个基础的函数模板关键字template后面接一对空的尖括号函数名后跟一对尖括号尖括号中指定需要特化的类型函数形参表: 必须要和模板函数的基础参数类型完全相同如果不同编译器可能会报一些奇怪的错误。
3.2类模板的特化
类模板的特化的步骤 1.必须要有基础的类模板 2.关键字template后面接一对空的尖括号 3.类名后跟一对尖括号,尖括号中指定需要特化的类型。 类模板的特化分为全特化和偏特化
3.2.1全特化
全特化即是将模板参数列表中所有的参数都确定化。
//函数模板的全特化
templateclass T1,class T2
class Ting
{
public:Ting(){cout TingT1,T2 endl;}
};
template
class Tingint,char
{
public:Ting(){cout Tingint,char endl;}
};
template
class Tingdouble, char
{
public:Ting(){cout Tingdouble,char endl;}
};int main()
{Tingint, float zft01;Tingdouble, char zft02;Tingint, char zft03;Tingfloat, int zft04;return 0;
}3.2.2偏特化
//函数模板的偏特化
templateclass T1, class T2
class Ting
{
public:Ting(){cout TingT1,T2 endl;}
};templateclass T1
class TingT1,int
{
public:Ting(){cout TingT1,int endl;}
};templateclass T1
class TingT1, double
{
public:Ting(){cout TingT1,double endl;}
};//还可以对某种类型参数做进一步限制 如
templateclass T1,class T2
class TingT1*,T2*
{
public:Ting(){cout TingT1*,T2* endl;}
};templateclass T1, class T2
class TingT1, T2
{
public:Ting(){cout TingT1,T2 endl;}
};int main()
{return 0;
}四、模板的分离编译
4.1模板不支持分离编译
比如有这样一个Add函数。如 .h文件
#pragma once
templateclass T
T Add(T x, T y);.cpp文件
#includeAdd.htemplateclass T
T Add(T x, T y)
{return x y;
}测试文件
//模板的分离编译
#includeAdd.h
int main()
{cout Add(1, 2) endl;return 0;
}运行时就会出现这样的报错。如
4.2模板分离编译报错的分析
为什么会这样呢 分析 C/C程序要运行一般要经历一下步骤 预处理—编译—汇编—链接
编译对程序按照语言特性进行词法、语法、语义分析错误检查无误后生成汇编代码。注意头文件不参与编译编译器对工程中的多个源文件是分离开单独编译的。 链接将多个obj文件合成一个并处理没有解决的地址问题。
4.2解决方案
第一种方法显示实例化 .cpp文件
#includeAdd.htemplateclass T
T Add(T x, T y)
{return x y;
}//显示实例化
template
int Add(int x,int y);
int Add(double x, double y);(以上的方法不推荐) 第二种方法将声明和定义放到一个文件 “xxx.hpp” 里面或者xxx.h其实也是可以的。推荐使用这种。
五、模板的总结
【优点】
模板复用了代码节省资源更快的迭代开发C的标准模板库(STL)因此而产生增强了代码的灵活性 【缺陷】模板会导致代码膨胀问题也会导致编译时间变长出现模板编译错误时错误信息非常凌乱不易定位错误