日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++模板显示实例化,显示具体化,隐式实例化

發布時間:2024/8/23 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++模板显示实例化,显示具体化,隐式实例化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數模板是C++新增的一種性質,它允許只定義一次函數的實現,即可使用不同類型的參數來調用該函數。這樣做可以減小代碼的書寫的復雜度,同時也便于修改(注:使用模板函數并不會減少最終可執行程序的大小,因為在調用模板函數時,編譯器都根據調用時的參數類型進行了相應實例化)。下面來看看函數模板的使用過程:

[cpp]?view plaincopy
  • struct?job??
  • {??
  • ????char?name[20];??
  • ????int?salary;??
  • };??
  • ??
  • template?<class?T>?//函數模板聲明,通用變量類型為T??
  • void?swap(T?&a,?T?&b);??
  • ??
  • void?showJob(const?job?&a);//打印job內容??
  • ??
  • using?std::cin;??
  • using?std::cout;??
  • using?std::endl;??
  • void?main(void)??
  • {??
  • ??
  • ????int?a?=?4;??
  • ????int?b?=?5;??
  • ????cout<<"Before?swap?a?=?"<<a<<"?b="<<b<<endl;??
  • ????swap(a,?b);??
  • ????cout<<"After?swap?a?=?"<<a<<"?b="<<b<<endl;??
  • ?????
  • ????job?jobA?=?{"coder",?10000};??
  • ????job?jobB?=?{"manager",?1000};????
  • ????cout<<"Before?swap";??
  • ????showJob(jobA);??
  • ????showJob(jobB);??
  • ????cout<<endl;??
  • ????swap(jobA,?jobB);??
  • ????cout<<"After?swap";??
  • ????showJob(jobA);??
  • ????showJob(jobB);??
  • ????cout<<endl;??
  • system("pause");??
  • };??
  • ??
  • template<class?T>?//函數模板實現??
  • void?swap(T?&a,?T?&b)??
  • {??
  • ????T?temp;??
  • ????temp?=?a;??
  • ????a?=?b;??
  • ????b?=?temp;??
  • }??
  • ??
  • void?showJob(const?job?&a)??
  • {??
  • cout<<"?"<<a.name<<"?=?"<<a.salary;??
  • }??

  • 如果在上述job結構互換過程中只想互換salary,而不換其他成員變量值那么怎么辦呢?C++中可以通過以下幾種方法來解決這一問題。

    1>顯式具體化
    顯式具體化也是基于函數模板的,只不過在函數模板的基礎上,添加一個專門針對特定類型的、實現方式不同的具體化函數。

    [cpp]?view plaincopy
  • template<>void?swap<job>(job?&a,?job?&b)??
  • {??
  • ?????int?salary;??
  • ?????salary?=?a.salary;??
  • ?????a.salary?=?b.salary;??
  • ?????b.salary?=?salary;??
  • }??


  • 如上所示,該具體化函數的實現與模板并不一致,編譯器解析函數調用時會選擇最匹配的函數定義。

    2>定義同名常規函數

    [cpp]?view plaincopy
  • void?swap(job?&a,?job?&b)??
  • {??
  • ?????int?salary;??
  • ?????salary?=?a.salary;??
  • ?????a.salary?=?b.salary;??
  • ?????b.salary?=?salary;??
  • }??

  • 由于編譯器在重載解析時,會選擇最匹配函數定義,所以在調用swap(jobA, jobB)時,編譯器會選擇void swap(job &a, job &b)函數定義,而屏蔽了模板函數。

    同時,模板函數也可以重載,其操作與常規函數一致。

    [cpp]?view plaincopy
  • template?<class?T>?void?swap(T?&a,?T?&b);??
  • ??
  • template?<class?T>?void?swap(T?&a,?T?&b,?T?&c);??
  • ??
  • ??
  • template?<typename?T>?void?swap(T?&a,?T?&b)??
  • {??
  • ????T?temp;??
  • ????temp?=?a;??
  • ????a?=?b;??
  • ????b?=?temp;??
  • }??
  • ??
  • template?<typename?T>?void?swap(T?&a,?T?&b,?T?&c)??
  • {??
  • ????T?temp;??
  • ????temp?=?a;??
  • ????a?=?b;??
  • ????b?=?c;??
  • ????c?=?temp;??
  • }??

  • 上面主要說的是函數模板的具體化,下面說下模板實例化。

    函數模板:

    [cpp]?view plaincopy
  • #define?MAXNAME?128??
  • struct?job??
  • {??
  • char?name[MAXNAME]:??
  • int?salary;??
  • };??
  • ??
  • template<class?T>??
  • void?swap(T?&a,?T?&b?)??
  • {??
  • ??T?temp;??
  • ??temp?=?a;??
  • ??a?=?b;??
  • ??b?=?temp;??
  • };??
  • ??
  • template?void?swap<int>(int?&a,?int?&?b);??//顯式實例化,只需聲明??
  • ??
  • template<>?void?swap<job>(job?&a,?job?&b)???//顯式具體化(上面已經講過,注意與實例化區分開,必須有定義)??
  • {??
  • ??int?salary:??
  • ??salary?=?a.salary:??
  • ??a.salary?=?b.salary;??
  • ??b.salary?=?salary;??
  • };//explicite?specialization.??

  • 類模板:

    [cpp]?view plaincopy
  • template?<class?T>??
  • class?Arrary??
  • {??
  • private:??
  • ??T*?ar;??
  • ??int?l;??
  • ...??
  • };//template?class?declaration.??
  • ??
  • template?class?Array<int>;???//explicit?instantiation.?顯式實例化??
  • ??
  • template<>?class?Array<job>??
  • {??
  • private:??
  • ??job*?ar;??
  • ??int?l;??
  • };//expicit?specialization.???顯式具體化,類定義體可以不同于類模板Array??


  • 相應的,隱式實例化指的是:在使用模板之前,編譯器不生成模板的聲明和定義實例。只有當使用模板時,編譯器才根據模板定義生成相應類型的實例。如:
    int i=0, j=1;
    swap(i, j); ?//編譯器根據參數i,j的類型隱式地生成swap<int>(int &a, int &b)的函數定義。
    Array<int> arVal;//編譯器根據類型參數隱式地生成Array<int>類聲明和類函數定義。

    顯式實例化:
    當顯式實例化模板時,在使用模板之前,編譯器根據顯式實例化指定的類型生成模板實例。如前面顯示實例化(explicit instantiation)模板函數和模板類。其格式為:
    template typename function<typename>(argulist);
    template class classname<typename>;
    顯式實例化只需聲明,不需要重新定義。編譯器根據模板實現實例聲明和實例定義。

    顯示具體化:
    對于某些特殊類型,可能不適合模板實現,需要重新定義實現,此時可以使用顯示具體化(explicite specialization)。顯示實例化需重新定義。格式為:
    template<> typename function<typename>(argu_list){...};
    template<>?class classname<typename>{...};

    綜上: template<> void swap<job>(job &a, job &b) {……};是函數模板的顯式具體化,意思是job類型不適用于函數模板swap的定義,因此通過這個顯式具體化重新定義;也可簡寫作template<> void swap(job &a, job &b); template void swap<job>(job &a, job &b);是函數模板的一個顯式實例化,只需聲明,編譯器遇到這種顯式實例化,會根據原模板的定義及該聲明直接生成一個實例函數,該函數僅接受job型。否則編譯器遇到模板的使用時才會隱式的生成相應的實例函數。 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的c++模板显示实例化,显示具体化,隐式实例化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。