1C++的第一个程序

一.模板进阶

1.1非模板类型参数

那之前学过的stack举例,在这之前我们如果要用N,就要用宏来定义,但是宏毕竟有局限性:

如果我要用到两个stack,一个要求10个空间,另一个要求100空间呢?

这时候有人可能会说把N定义为100不就行了。

确实,这样能解决当前的问题,但是会不会造成浪费?第一个stack是不是就浪费了90个空间。

所以为了解决这种问题,就引入了非模板类型参数:

这样就可以完美解决这个问题,需要多少空间我就开多少空间,就避免了浪费的问题。

当然,也是可以给缺省值的。

那么哪里会用到这种用法呢?

在C++11中引入的容器array就需要用到这种方式,那么这个容器是干什么的呢?

这东西和我们平常用的静态数组差不多,底层也是一个数组。

就连两个数组的大小也是一样的,基本没什么区别。

但是array是不允许你对数组进行修改,包括我们之前学的头部,尾部和中间的插入和删除,只能访问其中的数据,并且array并不会对数组中的数据进行初始化:

通过调试可以看出数组中的数据对视随机值。

这个容器呢用的不多,原因相信大家都知道:我有更好用的vector为什么不用呢?

那么array具体和我们日常用的静态数字有什么区别呢?

体现在越界的读和写方面:

在上面的代码中,很明显我们越界访问了,但是静态数组的越界读是不检查的,所以程序并不会报错。

而静态数组的写是抽查,可能越界几个会检查出来,后面就不一定检查出来。

而array的读和写都会检查,一旦出现越界访问,就会因为断言而报错。

最后目前非模板类型参数一般只支持整型,最新的编译器会支持double等类型,像自定义类型都是不支持的。

1.2特化

1.2.1概念

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能胡得到一些错误的结果,需要特殊处理,比如:是西安一个串门用来比较的函数模板:

1.2.2函数模板特化

那我们之前写过的Date类举例,此时我们传过去来比较两个日期的大小事没有问题的。

此时结果就出现错误,因为我们是用地址进行比较的,用地址去比较不是我们想要的,那么此时就需要用到特化:

这就是特化的基本应用,下面是特化的基本格式:

1.必须先有一个基础的函数模板

2.关键字template后面接一对空的尖括号<>

3.函数名后跟一对尖括号,尖括号中指定需要特化的类型4.函数形参表:必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误
 

更多推荐