前文当中说了,模板函数虽然非常好用,但是也存在一些问题。比如有的操作并不是对所有类型都适用的,针对这种情况 C++提供了一个解决方案,就是针对特定类型提供具体化的模板定义。这里的具体可以理解成类型的具体。
我们来看一个 C++ Primer 当中的例子,假设现在我们有一个结构体叫做 job:
struct job {
string name;
double salary;
int floor;
}
对于结构体是可以整体赋值的,所以之前的Swap
函数对它一样适用。
template <typename T>
void Swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
但我们现在希望在交换结构体的时候,只是交换salary
和floor
这两个字段,把name
保持不变。由于我们希望引入逻辑变化,所以直接调用Swap
函数就不可行了。
当然我们可以不用函数模板,直接重载函数:
void Swap(job &a, job &b) {
// swap为std自带的交换函数,在algorithm头文件中
swap(a.salary, b.salary);
swap(a.floor, b.floor);
}
由于 C++当中规定,非函数模板的优先级大于函数模板,所以我们在对job
结构体调用Swap
函数的时候,会优先使用这个。
除此之外,我们还可以提供一个具体化的模板函数:
template <> void Swap<job> (job &a, job &b) {
swap(a.salary, b.salary);
swap(a.floor, b.floor);
}
这个函数的写法看起来有些特殊,我们在函数类型之前加上了template <>
,在函数名后面又跟上了<job>
。它表示的是这是一个函数模板的显式具体化,也可以理解成为之前的函数模板提供一个job
类型的版本。C++当中规定显式模板函数的优先级高于普通模板函数。