C++模板元编程(3)模板显示具体化
作者:互联网
前面我们介绍了模板隐式实例化和显示实例化,今天介绍另外一个截然不同的概念,模板具体化。
来说说模板遇到的问题,也就是为什么要有模板具体化方法。模板函数自身有一定的局限性。由于其采用对对象类型的泛化处理,导致其在内部实现的细节上无法保证对所有类型的通用性。
假设定义了如下结构:
struct job {
char name[40];
double salary;
int floor;
};
又假设你希望能够交换这两个结构的内容。原来的模板将使用下面的代码来完成交换:
temp = a;
a = b;
b = temp;
由于C++允许将一个结构赋给另一个结构,因此即使T是一个job结构,上述代码也适用。然而,假设只想交换salary和floor成员,而不交换name成员,那么你就无法用模板重载重载来解决这个问题了(因为参数列表一样,都是job结构的引用),这时你可能就需要使用不同的代码。
然而,在C++中,你可以给模板提供一个具体化函数定义——称为具体显式化(explict specialization)。有点类似于函数重载,模板具体化给出了一份新的函数体。
对于job结构的非模板函数、模板函数和具体化的原型:
// 非模板函数原型
void Swap(job &, job &);
// 常规模板函数原型
template <typename T>
void Swap(T &, T &);
// 显示具体化模板函数原型
template <> void Swap<job>(job &, job &);
举个交换的例子:
// twoswap.cpp -- specialization overrides a template
#include<iostream>
using namespace std;
//模板函数模板声明
template <typename T>
void Swap(T &a, T &b);
struct job;
// explicit specialization 显示具体化声明
template <> void Swap<job>(job &j1, job &j2);
void Show(job &j);
struct job {
char name[40];
double salary;
int floor;
};
int main()
{
cout.precision(2);
cout.setf(ios::fixed, ios::floatfield);
int i = 10, j = 20;
cout << "i, j = " << i << ", " << j << ".\n";
cout << "使用编译器生成的交换函数:\n";
Swap(i, j);
cout << "Now i, j = " << i << ", " << j << ".\n";
job sue = { "Susan Yaffee", 73000.60, 7 };
job sidney = { "Sidney Taffee", 78060.72, 9 };
cout << "工作交换前:\n";
Show(sue);
Show(sidney);
Swap(sue, sidney); // 这里使用的是模板 void Swap(job &, jpb &)
cout << "After job swapping:\n";
Show(sue);
Show(sidney);
// cin.get();
system("pause");
}
// 模板函数
template <typename T>
void Swap(T &a, T &b) // general version
{
T temp;
temp = a;
a = b;
b = temp;
}
// 显示具体化
// swaps just the salary and floor fields of a job structure
template <> void Swap<job>(job &j1, job &j2)
{
double t1;
int t2;
// 交换salary
t1 = j1.salary;
j1.salary = j2.salary;
j2.salary = t1;
// 交换floor
t2 = j1.floor;
j1.floor = j2.floor;
j2.floor = t2;
}
void Show(job &j)
{
cout << j.name << ": $" << j.salary
<< " on floor " << j.floor << endl;
}
其中Swap中的是可选的,因为函数的参数类型表明,这是job的一个具体化,因此此处
template <> void Swap(job &j1, job &j2)
等价于下面这个更简洁的方式:
template <> void Swap(job &j1, job &j2)
需要注意的是,给出了具体化声明后,一定要有具体化的实现。模板函数具体化的匹配优先于模板函数,但非模板函数的匹配优先级是最高的,也就是说如果存在非模板函数Swap(job &j1, job &j2),那么将优先调用。
标签:void,j1,C++,job,Swap,具体化,模板 来源: https://blog.csdn.net/HandsomeHong/article/details/115427333