C++テンプレートの関数テンプレートのインスタンス化と具体化
5790 ワード
テンプレートはtemplateを宣言し、typenameはclassより最近C++標準に追加されました.
通常のテンプレート、テンプレートの具体化、非テンプレート関数の優先呼び出し順序.
非テンプレート関数(一般)>テンプレート関数の具現化>一般テンプレート
具現化の表示:
具体化は、特定のタイプの書き換え関数テンプレートとして表され、宣言の意味は独立しており、特定のタイプの関数定義が表示され、特定のタイプの関数定義が生成されることを意味します.
なぜ具体化を示すのですか?テンプレート関数で処理できない特殊な状況を処理します.明示的具体化明示的具体化も関数テンプレートに基づいているが、関数テンプレートに基づいて、特定のタイプに特化した、実装方法の異なる具体化関数を追加する.
キーワードtemplateの後に<>を含む具体化宣言を表示する.
次のようになります.
template<> void swap(job &j1, job &j2);
vs 2013はサポートされていません:
void swap(Any &a, Any &b);
struct job {
char name[40]; double salary;
int floor; };
template<> void swap(job &j1, job &j2);
void Show(job &j);
int main(){
using namespace std;
template void swap(job &, job &);
int i = 10, j = 20;
swap(i, j);
return 0;
}
template
void swap(Any &a, Any &b){ Any temp;
temp = a; a = b;
b = temp; }
template<> void swap(job &j1, job &j2){
double temp_sal; temp_sal = j1.salary;
j1.salary = j2.salary; j2.salary = temp_sal;
}
暗黙的インスタンス化
関数テンプレートの呼び出しが発生した場合、テンプレートのパラメータが表示されず、関数テンプレートと呼ばれる暗黙テンプレートの実パラメータ呼び出し(暗黙呼び出し)が行われます.次のようになります.
インスタンスを表示:
インスタンス:関数呼び出しswap(i,j)のように、intタイプを使用するコンパイラがswap()のインスタンスを生成します.
構文:宣言に必要な種類は<>記号でタイプを示し、宣言前にキーワードtemplateを追加します.
なぜインスタンス化が表示されるのですか?実際、コンパイラは関数を呼び出すときだけ関数を使用します.表示インスタンス化を使用しないと、関数を呼び出すたびに、テンプレートはどのタイプの関数を使用しているのかを導くためにパフォーマンスを消費し、プログラムの実行時の負担が増加します.表示インスタンス化を使用すると、コンパイル時に関数選択が処理されます. template[関数戻りタイプ][関数テンプレート名](関数パラメータリスト) インスタンス化の例:
template void swap(int, int);
注:同じファイル(または変換ユニット)で同じタイプの表示インスタンス化と具現化宣言の表示を使用しようとすると、エラーが発生します.
推奨:関数呼び出し時にインスタンス化宣言を表示せずにインスタンス化を直接表示できます.
次のようになります.
模範コード:
まとめ:
暗黙的インスタンス化とは、テンプレートを使用する前に、コンパイラがテンプレートの宣言および定義インスタンスを生成しないことを意味します.コンパイラは、テンプレートを使用する場合にのみ、テンプレート定義に基づいて対応するタイプのインスタンスを生成します.例えば、int i=0、j=1;swap(i, j);//コンパイラはパラメータi,jのタイプに基づいてswap(int&a,int&b)の関数定義を暗黙的に生成する.Array arVal;//コンパイラは、タイプパラメータに基づいてArrayクラス宣言とクラス関数定義を暗黙的に生成します.
明示的インスタンス化:テンプレートを明示的にインスタンス化する場合、コンパイラはテンプレートを使用する前に、明示的インスタンス化で指定したタイプに基づいてテンプレートインスタンスを生成します.インスタンス化(explicit instantiation)テンプレート関数とテンプレートクラスが前に表示されます.フォーマットはtemplate typename function(argulist);template class classname;明示的なインスタンス化は宣言するだけで、再定義する必要はありません.コンパイラは、テンプレートに基づいてインスタンス宣言とインスタンス定義を実装します.
具現化の表示:特定のタイプでは、テンプレート実装に適していない場合があり、実装を再定義する必要がある場合は、表示具現化(explicite specialization)を使用します.インスタンス化の表示は再定義する必要があります.フォーマットは、template<>typename function(argu_list){...}です.template<> class classname{...};
転載先:https://www.cnblogs.com/cthon/p/9203234.html
通常のテンプレート、テンプレートの具体化、非テンプレート関数の優先呼び出し順序.
非テンプレート関数(一般)>テンプレート関数の具現化>一般テンプレート
具現化の表示:
具体化は、特定のタイプの書き換え関数テンプレートとして表され、宣言の意味は独立しており、特定のタイプの関数定義が表示され、特定のタイプの関数定義が生成されることを意味します.
なぜ具体化を示すのですか?テンプレート関数で処理できない特殊な状況を処理します.明示的具体化明示的具体化も関数テンプレートに基づいているが、関数テンプレートに基づいて、特定のタイプに特化した、実装方法の異なる具体化関数を追加する.
キーワードtemplateの後に<>を含む具体化宣言を表示する.
次のようになります.
template<> void swap(job &j1, job &j2);
vs 2013はサポートされていません:
void swap(Any &a, Any &b);
struct job
char name[40];
int floor;
using namespace std;
template void swap(job &, job &);
int i = 10, j = 20;
swap(i, j);
}
void swap(Any &a, Any &b){
temp = a;
b = temp;
double temp_sal;
j1.salary = j2.salary;
}
暗黙的インスタンス化
関数テンプレートの呼び出しが発生した場合、テンプレートのパラメータが表示されず、関数テンプレートと呼ばれる暗黙テンプレートの実パラメータ呼び出し(暗黙呼び出し)が行われます.次のようになります.
template void func(T t)
{
cout<
インスタンスを表示:
インスタンス:関数呼び出しswap(i,j)のように、intタイプを使用するコンパイラがswap()のインスタンスを生成します.
構文:宣言に必要な種類は<>記号でタイプを示し、宣言前にキーワードtemplateを追加します.
なぜインスタンス化が表示されるのですか?実際、コンパイラは関数を呼び出すときだけ関数を使用します.表示インスタンス化を使用しないと、関数を呼び出すたびに、テンプレートはどのタイプの関数を使用しているのかを導くためにパフォーマンスを消費し、プログラムの実行時の負担が増加します.表示インスタンス化を使用すると、コンパイル時に関数選択が処理されます.
template void swap
注:同じファイル(または変換ユニット)で同じタイプの表示インスタンス化と具現化宣言の表示を使用しようとすると、エラーが発生します.
推奨:関数呼び出し時にインスタンス化宣言を表示せずにインスタンス化を直接表示できます.
次のようになります.
template
T add(T x,T y)
{
return x+y;
}
int main()
{
int i1=2,i2=3;
add(i1,i2);
template int add(i1,i2);//
return 0;
}
模範コード:
///**********************************************
/// @file templetAdd.cc
/// @author alex([email protected])
/// @date 2018-06-19 21:42:20
///**********************************************/
#include
#include
using std::cout;
using std::endl;
// --> -->
// ( )
// -->
//< >
//1、 class typename
//2、 、 ( )
template
T add(T x,T y)
{
return x + y;
}
#if 0
template int add(int x,int y)//
{
cout< int add(int x,int y)// template<>int add(int x,int y)
{
cout<// ,
const char* add(const char*lhs,const char* rhs)
{
char*tmp = new char[strlen(lhs)+strlen(rhs)+1]();
strcpy(tmp,lhs);
strcat(tmp,rhs);
return tmp;
}
#if 0
//
//
int add(int x,int y)// ,
{
return x + y;
}
#endif
//
//
template
T add(T x,T y,T z);
//c++11
//c++11 ,
// (bool、char、int、long、long long)
template
int func(T x,T y)
{
return x*y*num;
}
int main()
{
int a=3,b=4;
double c1=1.2,c2=2.3,c3=4.9;
char ch1='a',ch2=2;
//template char add(char x,char y);// ( ) ,
func(ch1,ch2);
const char *p1="hello";
const char *p2="good";
cout << "int + int = " << add(a,b) << endl;//
cout << "double + double = " << add(c1,c2) << endl;//
cout << "char + char = " << add(ch1,ch2) << endl;
cout << "double + double = " << add(c1,c2,c3) << endl;
cout << "int + int = " << func(a,b) << endl;//
//cout << "a+d1=" << add(a,c1) << endl;//error,
cout << add(p1,p2) << endl;
return 0;
}
//
template
T add(T x,T y,T z)
{
return x +y + z;
}
まとめ:
暗黙的インスタンス化とは、テンプレートを使用する前に、コンパイラがテンプレートの宣言および定義インスタンスを生成しないことを意味します.コンパイラは、テンプレートを使用する場合にのみ、テンプレート定義に基づいて対応するタイプのインスタンスを生成します.例えば、int i=0、j=1;swap(i, j);//コンパイラはパラメータi,jのタイプに基づいてswap(int&a,int&b)の関数定義を暗黙的に生成する.Array arVal;//コンパイラは、タイプパラメータに基づいてArrayクラス宣言とクラス関数定義を暗黙的に生成します.
明示的インスタンス化:テンプレートを明示的にインスタンス化する場合、コンパイラはテンプレートを使用する前に、明示的インスタンス化で指定したタイプに基づいてテンプレートインスタンスを生成します.インスタンス化(explicit instantiation)テンプレート関数とテンプレートクラスが前に表示されます.フォーマットはtemplate typename function(argulist);template class classname;明示的なインスタンス化は宣言するだけで、再定義する必要はありません.コンパイラは、テンプレートに基づいてインスタンス宣言とインスタンス定義を実装します.
具現化の表示:特定のタイプでは、テンプレート実装に適していない場合があり、実装を再定義する必要がある場合は、表示具現化(explicite specialization)を使用します.インスタンス化の表示は再定義する必要があります.フォーマットは、template<>typename function(argu_list){...}です.template<> class classname{...};
転載先:https://www.cnblogs.com/cthon/p/9203234.html