当前位置:   article > 正文

模板的显示实例化与显示具体化_显示实例化类中模板函数

显示实例化类中模板函数

显式实例化:
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>;   //注意显示实例化的语法,用<>符号指示类型
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

当保留最后一行的时候,编译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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/332889
推荐阅读
相关标签
  

闽ICP备14008679号