zoukankan      html  css  js  c++  java
  • 实例化和具体化详解

    primer Plus在解释具体化和实例化看的有点乱,分解出来备忘

    在代码中包含函数模板本身并不会生成函数定义,它只是用于生成函数定义的方案

    编译器使用模板为我写类型生成函数定义时,得到的是模板实例

    如这个模板

    template<typename T>
    void Swap(T &t1,T &t2)
    {
        T _t;
        _t=t1;    
        t1=t2;
        t2=_t;
    }

    调用

        int i = 10,j=20;
        ::cout<<"i, j ="<<i<<" , "<<j<<endl;
        cout<<" Using compiler -generated int swapper:
    ";
        Swap(i,j);
        ::cout<<"Now i, j ="<<i<<" , "<<j<<endl;

    调用 Swap(i,j)导致编译器生成Swap()的一个实例,该实例使用int类型。模板并非函数定义,但使用int的模板实例是函数定义。
    这种实例化方式被称为隐式实例化,编译器之所以知道需要进行定义,是由于程序调用Swap()函数时提供了int 参数。

    c++还允许显示实例化

    其语法是,声明所需的种类用<>指示类型并在声明前加上template:

    template void Swap<int>(int &t1,int &t2);

    例子

    #include<iostream>
    using namespace std;
    
    template<typename T>
    void Swap(T &t1,T &t2);
    
    template void Swap<int>(int &t1,int &t2);
    
    int main()
    {
        cout<<" Using compiler -generated int swapper:
    ";
        int i = 10,j=20;
        cout<<"i, j ="<<i<<" , "<<j<<endl;    
        cout<<" Using compiler -generated int swapper:
    ";
        Swap(i,j);
        cout<<"Now i, j ="<<i<<" , "<<j<<endl;    
        cin.get();
    }
    
    template<typename T>
    void Swap(T &t1,T &t2)
    {
        T _t;
        _t=t1;    
        t1=t2;
        t2=_t;
    }


    显示具体化的原型和定义应以template<>打头,并通过名称来指出类型。

    显式具体化优先于常规模板,而非模板函数优先于具体化和常规模板

    与显式实例化不同的是,显式具体化使用下面的声明方式 ,两种方式是一样的

    template<> void Swap<job>(job &c1,job &c2);
    template<> void Swap(job &c1,job &c2);

    这们的意思是不要使用Swap()模板来生成函数定义,而使用专门的job类型显式地定义函数定义
    显式具体化声明在关键字template 后加<>,显式实例化没有

    具体化小例子

    #include<iostream>
    using namespace std;
    
    struct job
    {
        char name[40];
        double salary;
        int floor;
    };
    template<typename T>
    void Swap(T &t1,T &t2);
    template<> void Swap<job>(job &c1,job &c2);
    
    void show(job j);
    int main()
    {
        
    
        job sue={"Suan Yaffee",73000.123,7};
        job sidey={"Sidney Taffee",78060.1,2};
        cout<<"sue:
    ";
        show(sue);
        cout<<"sidey:
    ";
        show(sidey);
        Swap(sue,sidey);
        cout<<"sue:
    ";
        show(sue);
        cout<<"sidey:
    ";
        show(sidey);
        cin.get();
    }
    
    template<typename T>
    void Swap(T &t1,T &t2)
    {
        T _t;
        _t=t1;    
        t1=t2;
        t2=_t;
    }
    
    template<> void Swap<job>(job &j1,job &j2)
    {
        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<<"name :"<<j.name<<"  salary:  "<<j.salary<<" floor :  "<<j.floor<<endl;
    }
  • 相关阅读:
    《java并发编程实战》读书笔记9--并发程序的测试
    《java并发编程实战》读书笔记8--死锁,性能与可伸缩性,锁粒度锁分解锁分段
    笔试算法题记录1
    _stdcall调用
    通信设备硬件工程师应该具备的基本能力和知识
    PCB产业链、材料、工艺流程详解(1)
    PCB中加入任意LOGO图文说明 精心制作
    开关电源基础知识(一)
    六个框架,一百多条检查项目,保证PCB设计不再出错
    开关电源PCB排版,基本要点分析
  • 原文地址:https://www.cnblogs.com/li-peng/p/3479994.html
Copyright © 2011-2022 走看看