在泛型的学习中我们用到了类型模板。例如以下程序片段:

1
2
3
4
5
6
7
8
9
10
template<typename T>
class foo{
T bar;
...
}

template<typename S>
S fec(S arg){
...
}

但是template的用法不止于此。还有一种非类型模板。这种方法可以减小程序的开销,增强代码的复用性。

例如以下程序片段:

1
2
3
4
template<typename C,int N>
void sort(C (&pos)[N]){
...
}

这个方法可以完整地传入一个数组,而不是退化的指针,包括数组长度都被传入,这样有利于预防数组越界的问题。

当然,这样的方法只允许我们传入一个数组名,而不是首地址指针,因为template的实例化是在预编译时完成的,数组必须是固定长度申请的,因此c++的新特性,即变量长度定义的数组在这里不适用。

由此看来,typename和nullptr有一种设计哲学上的共性,他们通过对全体类型的抽象,而在使用时隐式地转换为所调用的具体类型。相同的,他们的实现都是在预编译的过程中实现的,其本身只是语法上的助记符而已。