C++ 函式模板 例項化和具體化
https://blog.csdn.net/qq_30835655/article/details/76850894
函式模板是C++新增的一種性質,它允許只定義一次函式的實現,即可使用不同型別的引數來呼叫該函式。這樣做可以減小程式碼的書寫的複雜度,同時也便於修改。但是,在程式碼中包含函式模板本身並不會生成函式定義,它只是一個用於生成函式定義的方案。編譯器使用模板為特定型別生成函式定義時,得到的是模板例項(instantiation)。
1 例項化
例項化有兩種形式,分別為顯式例項化和隱式例項化。模板並非函式定義,例項式函式定義。
1.1 顯式例項化(explicit instantiation)
顯式例項化意味著可以直接命令編譯器建立特定的例項,有兩種顯式宣告的方式。
比如存在這麼一個模板函式
template <typename T>
void Swap(T &a, T &b)
第一種方式是宣告所需的種類,用<>符號來指示型別,並在宣告前加上關鍵詞template,如下:
template void Swap<int>(int &, int &);
第二種方式是直接在程式中使用函式建立,如下:
Swap<int>(a,b);
顯式例項化直接使用了具體的函式定義,而不是讓程式去自動判斷。
1.2 隱式例項化(implicit instantiation)
隱式例項化比較簡單,就是最正常的呼叫,Swap(a,b),直接導致程式生成一個Swap()的例項,該例項使用的型別即引數a和b的型別,編譯器根據引數來定義函式例項。
2 具象化(顯式)
思考這麼一個問題,當前的Swap模板交換輸入的兩個物件,可能式基本型別也可能式自定義類。如果有這麼一個需求,需要交換自定義類裡的某一個屬性而不是整個類,那麼Swap模板就不可用,因為Swap模板交換的是整個類。
顯式具體化將不會使用Swap()模板來生成函式定義,而應使用專門為該特定型別顯式定義的函式型別。有兩種定義形式,如下,其中job為使用者自定義類
template <> void Swap(job &a, job &b)
template <> void Swap<job>(job &a, job &b)
顯式具體化在聲明後,必須要有具體的實現,這是與顯示例項化不同的地方。
3 舉例
下面通過一個程式來觀察例項化和具體化,加深理解。
/*************************************************************************
> File Name: array.cpp
> Author:
> Mail:
> Created Time: Sat 05 Aug 2017 01:20:31 AM PDT
************************************************************************/
#include<iostream>
#include<string>
using namespace std;
struct job
{
string name;
int salary;
job(string _name,int _salary):name(_name),salary(_salary){};
};
//template prototype
template <typename T>
void Swap(T &a, T &b){
T temp;
temp = a;
a = b;
b = temp;
}
//explict specialization for job 顯式具體化
template <> void Swap(job &a, job &b)
{
int temp;
temp = a.salary;
a.salary = b.salary;
b.salary = temp;
}
template void Swap<int>(int &, int &);
int main()
{
char a = 'a', b = 'b';
cout<<"a: "<<a<<" ; b: "<<b<<endl;
Swap(a,b); //1 implicit template instantiation for char 隱式例項化
cout<<"a: "<<a<<" ; b: "<<b<<endl;
int c = 1, d = 2;
cout<<"c: "<<c<<" ; d: "<<d<<endl;
Swap(c,d); //2 use explicit template instantiation for int 顯式例項化
cout<<"c: "<<c<<" ; d: "<<d<<endl;
Swap<int>(c,d); //3 use explict template instantiation for int 顯式例項化
cout<<"c: "<<c<<" ; d: "<<d<<endl;
job e("lucy",100), f("bob",200);
cout<<"lucy: "<<e.name<<" "<<e.salary<<" ; bob: "<<f.name<<" "<<f.salary<<endl;
Swap(e,f); //use explict specialization for job 呼叫顯式具體化
cout<<"lucy: "<<e.name<<" "<<e.salary<<" ; bob: "<<f.name<<" "<<f.salary<<endl;
}
輸出
➜ cpptest ./a.out
a: a ; b: b
a: b ; b: a
c: 1 ; d: 2
c: 2 ; d: 1
c: 1 ; d: 2
lucy: lucy 100 ; bob: bob 200
lucy: lucy 200 ; bob: bob 100
備註:隱式例項化和顯式例項化和顯式具體化統稱為具體化,它們的相同在於都用了具體型別的函式定義,而不是通用描述。
---------------------
作者:尹小賤
來源:CSDN
原文:https://blog.csdn.net/qq_30835655/article/details/76850894
版權宣告:本文為博主原創文章,轉載請附上博文連結!