天津网站建设求职简历,做国外进口衣服的网站好,小制作废品利用,展示形网站开发1、非类型模版参数 模版参数分为类类型形参和非类型形参 类类型形参#xff1a;出现在参数列表中#xff0c;跟在class或者typename之类的参数类型名称 非类型形参#xff1a;就是用一个常量作为类#xff08;函数#xff09;模版的一个参数#xff0c;在类#xff08;函…1、非类型模版参数 模版参数分为类类型形参和非类型形参 类类型形参出现在参数列表中跟在class或者typename之类的参数类型名称 非类型形参就是用一个常量作为类函数模版的一个参数在类函数模版中可将该参数当成常量来使用 namespace bite
{//定义一个模版类型的静态数组templateclass T, size_t N 10class array{public:T operator[](size_t index) { return _array[index]; }const T operator[](size_t index)const { return _array[index]; }size_t size()const { return _size; }bool empty()const { return 0 _size; }private:T _array[N];size_t _size;};
}注意 浮点数、类对象以及字符串是不允许作为非类型模版参数的非类型的模版参数必须在编译期就能确认结果 2、模版的特化
概念
通常使用模版可以实现一些与类型无关的代码但对于一些特殊类型的可能会得到一些错误的结果需要特殊处理例如实现了一个专门用来进行小于比较的函数模版
templateclass T
bool Less(T left, T right)
{return left right;
}int main()
{cout Less(1, 2) endl; //结果正确Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout Less(d1, d2) endl;//结果正确Date* p1 d1;Date* p2 d2;cout Less(p1, p2) endl;//结果错误return 0;
} 可以发现Less在绝大多数情况可以正常比较但是比如在上述情况就会出现错误 因为Less内部并没有比较p1和p2指向的对象内容而比较的是p1和p2指针的地址就无法达到预期而错误 此时就需要对模版进行特化。即在原模版类的基础上针对特殊类型所进行特殊化的实现方式。模版特化中分为函数模版特化与类模版特化 函数模版特化 函数模版的特化步骤: 必须要先有一个基础的函数模版关键字template后接上一对空的尖括号函数名后跟上一对尖括号尖括号中指定需要特化的类型函数形参表必须要和模版函数的基础参数类型完全相同不然编译器会出现一些奇怪的错误 templateclass T
bool Less(T left, T right)
{return left right;
}//对Less函数模版进行特化
template
bool LessDate*(Date* left, Date* right)
{return *left *right;
}int main()
{cout Less(1, 2) endl; //结果正确Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout Less(d1, d2) endl;//结果正确Date* p1 d1;Date* p2 d2;cout Less(p1, p2) endl; //结果正确return 0;
}注意一般情况下如果函数模版遇到不能处理或者处理有误的类型为了实现简单通常都是将该函数直接给出 bool Less(Date* left, Date* right)
{return *left *right;
} 类模版特化
全特化 全特化就是将模版参数列表中所有参数都确定化 templateclass T1,class T2
class Date
{
public:Date() { cout DateT1, T2 endl; }
private:T1 _d1;T2 _d2;
};template
class Dateint, char
{
public:Date() { cout Dateint, char endl; }
private:int _d1;int _d2;
};int main()
{Dateint, int d1;Dateint, char d2;return 0;
}偏特化 偏特化任何针对模版参数进一步进行条件限制的特化版本比如以下模版类 templateclass T1,class T2
class Data
{
public:Date() { cout DataT1, T2 endl; }
private:T1 _d1;T2 _d2;
};偏特化有以下两种特化方式 1、部分特化将模版参数类表中的一部分参数特化 // 将第二个参数特化为int
template class T1
class DataT1, int
{
public:Data() { cout DataT1, int endl; }
private:T1 _d1;int _d2;
}; 2、参数更进一步的限制 偏特化并不仅仅是指特化部分参数而是针对模版参数更进一步的条件限制所设计出来的一个特化版本 //两个参数偏特化为指针类型
templatetypename T1, typename T2
class DataT1*, T2*
{
public:Data() { cout DataT1*, T2* endl; }
private:T1 _d1;T2 _d2;
};//两个参数偏特化为引用类型
templatetypename T1,typename T2
class DataT1, T2
{
public:Data(const T1 d1, const T2 d2): _d1(d1), _d2(d2){cout DataT1, T2 endl;}
private:const T1 _d1;const T2 _d2;
};int main()
{Datadouble, int d1;//调用特化的int版本Dataint, double d2;//调用基础的模版Dataint*, int* d3;//调用特化的指针版本Dataint, int d4(1, 2);//调用特化的引用版本return 0;
}类模版特化应用实例 有如下专门用来按照小于比较的类模版Less templateclass T
//仿函数
struct Less
{bool operator()(const T x, const T y)const{return x y;}
};int main()
{Date d1(2022, 7, 7);Date d2(2022, 7, 3);Date d3(2022, 7, 9);vectorDate v1;v1.push_back(d1);v1.push_back(d2);v1.push_back(d3);//可以直接排序结果是日期排序sort(v1.begin(), v1.end(), LessDate());vectorDate* v2;v2.push_back(d1);v2.push_back(d2);v2.push_back(d3);//可以直接排序结果错误日期还不是升序而v2中放的地址是升序//此处需要在排序过程中让sort比较v2中存放地址指向的日期对象//但是走Less模版sort在排序时实际比较的是v2中指针的地址因此无法达到预期sort(v2.begin(), v2.end(), LessDate*());return 0;
} 我们可以发现对于日期对象可以直接排序并且结果是正确的。但是如果待排序元素是指针结果就不一定正确。因为sort最终按照Less模版中方式比较所以只会比较指针而不是比较指针指向空间中内容此时可以使用类版本特化来处理问题 template
struct LessDate*
{bool operator()(Date* x, Date* y) const{return *x *y;}
}; 此时运行以上代码就是正确的 3、模版分离编译
什么是分离编译 一个程序项目由若干个源文件共同实现而每个源文件单独编译生成目标文件最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式 模版的分离编译 假设有以下场景模版的声明与定义分离开在头文件中进行声明在源文件中完成定义 // a.h
templateclass T
T Add(const T left, const T right);// a.cpp
templateclass T
T Add(const T left, const T right)
{return left right;
}// main.cpp
#includea.h
int main()
{Add(1, 2);Add(1.0, 2.0);return 0;
} 此时编译器会报错无法解析的外部符号。因为这两个函数没有实例化生成具体代码因此链接时报错。