模板的显示实例化与显示具体化

显式实例化:
C++中模板函数(类)的调用与定义分离时,需要使用显式实例化,否则就会出现链接错误。
编译器对各个cpp分别编译的时候,模板函数必须被实例化编译。如果我们把调用与定义写在一个文件,在调用语句处有int a, b; cmp(a, b); 那么编译器就会知道我们将要使用cmp,然后结合该模板函数的定义语句,最后就编译出这么一个函数。问题就出现在我们把调用与定义写在不同的文件里,当编译器编译定义函数的cpp的时候,即便这个cpp有include该模板函数的头文件,编译器仍然不知道你的实例化typename是什么,因此这个.o就不会含实例化的函数。而编译器编译调用函数的cpp的时候,即便这个cpp也include了函数的头文件,但是由于没有定义,这个.o也不含实例化的函数。最后链接该定义cpp的.o和调用cpp的.o的时候,会找不到相应的实例化函数而报错。

//Example.h
template<class T>
class Test {
    public:
        Do(T a);
};
 
//Example.cpp
#include "Example.h"
 
template<class T>
Test::Do(T a) {
    //do nothing...
}
 
//template class Test<int>;   //注意显示实例化的语法,用<>符号指示类型

当保留最后一行的时候,编译Example.cpp输出汇编语言会得到一大块东西,而注释掉最后一行后就只剩下
.file “Example.cpp”
.ident “GCC: (tdm64-2) 4.8.1”
显然是没有代码被生成的,调用cpp产生的.o在链接example.o的时候就会出现链接错误。

显式具体化:
假设定义了如下结构:
struct job
{
char name[40];
double salary;
int floor;
};
另外,假设希望能够交换两个这种结构的内容。原来的模板使用下面的代码来完成交换:
temp = a;
a = b;
b = temp;
原来的模板使用下面的代码来完成交换, 它只能完成int,float等常规类型变量的交换,而如果是自定义的复杂结构体,则无法处理。因此类似于重载一样,我们要具体化一个特例template<> void Swap(job &j1, job &j2):

template<typename T>
void Swap(T &a, T &b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}
template<> void Swap<job>(job &j1, job &j2)//显式具体化在关键字template后包含<>,而显式实例化没有
{
    double t1;
    int t2;
    t1 = j1.salary;
    j1.salary = j2.salary;
    j2.salary = t1;
    t2 = j1.floor;
    j1.floor = j2.floor;
    j2.floor = t2;
}
void Show(job &j)
{
    cout << j.name << ": $" << j.salary
         << " on floor " << j.floor << endl;
}
int main()
{
    cout.precision(2);
    cout.setf(ios::fixed, ios::floatfield);
    int i = 10, j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    cout << "Using compiler-generated int swapper:\n";
    Swap(i, j);
    cout << "Now i, j = " << i << ", " << j << ".\n\n";
 
    job sue = {"Susan Yaffee", 73000.60, 7};
    job sidney = {"Sidney Taffee", 78060.72, 9};
    cout << "Before job swapping:\n";
    Show(sue);
    Show(sidney);
    Swap(sue, sidney);
    cout << "After job swapping:\n";
    Show(sue);
    Show(sidney);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值