网站备案 强制,易企秀电脑版,网站开发进度计划,网站备案负责人【C笔记】模板进阶 一、非类型模板参数二、类模板的特化三、模板的分离编译 一、非类型模板参数
我们之前学过的模板虽然能很好地帮我们实现泛型编程#xff0c;比如我们可以让一个栈存储int类型的数据#xff0c;一个栈存储double类型的数据#xff1a;
template cla… 【C笔记】模板进阶 一、非类型模板参数二、类模板的特化三、模板的分离编译 一、非类型模板参数
我们之前学过的模板虽然能很好地帮我们实现泛型编程比如我们可以让一个栈存储int类型的数据一个栈存储double类型的数据
template class T
class Stack {
public :Stack() {cout Stack() endl;}~Stack() {cout ~Stack() endl;}
private :T* _data;
}int main() {Stackint st1;Stackdouble st2;return 0;
}但是如果我们想实现两个静态的栈一个容量为10另个一容量为100那就没有办法了。
对此C又引入了一个非类型模板参数
template class T, size_t N
class Stack {
public:Stack() {cout Stack() endl;}~Stack() {cout ~Stack() endl;}
private:T data[N];
}这样我们就可以在实例化的时候给上对应的容量了
int main() {Stackint, 10 st1;Stackdouble, 100 st2;return 0;
}需要注意的是 非类型模板参数一定要是常量不能是变量 非类型模板参数一定要是整型(包括整型家族的所有成员char、short……) 直到C20版本才引入。
二、类模板的特化
模板的特化就是针对某些类型进行特殊化处理。 比如我们现在随便写一个类模板 如果我们想针对两个参数一个是int一个是double的这种情况特殊处理让它输出不同的内容就可以使用特化 上面的这种叫做全特化与之对应的还有偏特化 在匹配的时候也是遵循最匹配原则看哪个最符合条件就匹配哪个。
而且在特化的时候也并不需要写的很具体其实也可以像下面这样写
特化必须要有原模板也就是最初的没有任何特化的模板。
三、模板的分离编译
模板其实是不支持分离编译的即声明和定义分离(声明在一个文件定义在另个文件)。 这样做的话会发生连接错误
而我们若是讲一个普通函数分离编译就没问题
这其中的原因是因为函数模板比普通函数多了一个步骤实例化因为函数模板其实和具体函数其实是一个一对多的关系一个函数模板可以实例化出很多个功能相近但参数和返回值类型不同的函数。 也就是说我们在Stack.cpp中所写的可以比作一个骨架从中只能得到这个函数的实现逻辑所以在编译Stack.cpp的时候并不能生成具体的函数地址这样main函数在调用的时候就自然找不到了。
解决这个问题的其中一种方法就是显示实例化
但这种方法并不是一种很好的方法因为它每一次只能解决一种类型而且每一种类型都得要显示声明一次这会是代码用于。
还有一种方法就是直接将声明和定义放在同一个文件里