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

显式实例化:
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;
}
展开阅读全文

模板显示具体化的一个问题。

09-16

为什么下面程序会报错“ “swap”: 对重载函数的调用不明确rn1> c:\users\coo\documents\visual studio 2010\projects\cjiajia\cjiajia\main.cpp(46): 可能是“void swap(Person &,Person &)”rn1> c:\program files\microsoft visual studio 10.0\vc\include\utility(100): 或 “void std::swap(_Ty &,_Ty &)””rnrn根据C++ primer plus(第六版)的p286上写的,模板的显式具体化会优先于模板函数执行?为什么会报错对 重载函数的调用不明确呢?rnrnrn[code=c]rn#include rnusing namespace std;rnrnrnclass Personrnrn friend ostream & operator <<(ostream& os,Person& p);rn template rn friend void swap(T& t1, T& t2);rnprivate:rn char *name;rn int age;rnpublic:rn Person(char* name,int age)this->name=name; this->age=age;;rn void setName(char* name)this->name=name;;rn void setAge(int age)this->age=age;;rn;rnrnostream& operator<< (ostream& os,Person& p) rn os << "name: " << p.name << endl;rn os << "age: " << p.age << endl;rn return os;rnrnrnrn//函数模板rntemplate rnvoid swap(T& t1, T& t2)rnrn T t = t1;rn t1 = t2;rn t2 = t;rn cout <<"3模板函数swap------------------------------" << endl;rnrnrn//显式具体化 : 只交换两个对象的年龄rntemplate<> void swap(Person& p1, Person& p2)rnrn int tmp = p1.age;rn p1.age = p2.age;rn p2.age = tmp;rn cout << "2显式具体化swap----------------------------" << endl;rnrnrnrnint main()rnrn Person p1("张三",23);rn Person p2("李四",15);rn cout<<"p1: " << p1 <<"p2: " << p2 < 论坛

没有更多推荐了,返回首页