编程语言
首页 > 编程语言> > C++模板元编程(3)模板显示具体化

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