C++テンプレートの特化問題について簡単に述べる.
4313 ワード
C++にはクラステンプレートと関数テンプレートの2種類のテンプレート方式があり,テンプレート特化も全特化と偏特化の2種類に分けられる.
まず次のテンプレートを見てみましょう
一般的なテンプレートの定義形式に詳しいと思いますが、ここではテンプレートの特化時の定義形式についてお話しします.
テンプレートの特化とは何でしょうか.どんな役割がありますか.テンプレートの特化はテンプレートの具体化とも呼ばれ、テンプレートパラメータが特定のタイプで具体的に実現されることを指す.テンプレートのインスタンス化時にテンプレートの優先度を合わせるために使用されます.
テンプレートでの優先順位の一致:テンプレートのフル特化>テンプレートの偏特化>通常のテンプレート
テンプレート偏特化は、既存のテンプレートに対して部分的に具体化され、元のテンプレートパラメータリストのいくつかの汎用パラメータを特定のタイプに指定するために使用されます.上記コードでは、テンプレートパラメータリストのT 1を特定のタイプのcharとして指定する、2番目のテンプレートパラメータT 2は指定されていない、クラステンプレートをインスタンス化する必要がある場合、指定したテンプレートの1番目のパラメータタイプがcharである場合、通常のテンプレートよりもマッチング度が高いため、このオフセットバージョンを優先してインスタンス化するもちろん、これは、特定のフル特化バージョンがない場合、フル特化が一致し、偏特化や通常のテンプレートよりも優先度が高いためです.
上記のコードに示すように、s 1オブジェクトのインスタンス化にはcharとintタイプが1つ提供され、1つ目のタイプはBaseテンプレートのオフセットとちょうど一致するので、このオフセット化バージョンを優先してオブジェクトをインスタンス化するので、s 1.show()は#2の文を出力します.
s 2オブジェクトは2つのintタイプを提供し、これはテンプレートのフル特化バージョンと偏特化バージョンと一致しないため、通常のテンプレートを用いてインスタンス化する.show()ですので#1の文を出力します.
s 3オブジェクトは2つのdoubleタイプを提供し、これはテンプレートのフル特化と一致するので、このテンプレートのフル特化バージョンを用いてインスタンス化する、s 3.show()は#3の文を出力します.
上のコードの実行後の出力:
関数テンプレートの定義形式はクラステンプレートと似ていますが、現在の関数テンプレートではオフセットは許可されず、フル特化のみが許可されていますが、関数テンプレートは関数テンプレートの再ロードによって「オフセット」を実現できます.コード:
上記のコード$1関数では、2つのintタイプを関数テンプレートのタイプパラメータとして使用します.一致する特化バージョンは存在しないため、コンパイラは通常の関数テンプレートを使用して関数を定義し、プログラムに呼び出され、$2が1文を呼び出して出力します.ここまで$2は他のテンプレート関数呼び出し形式とは異なり、テンプレートパラメータのタイプを指定していないことがわかりました.これも許可されています(関数テンプレートのみ)コンパイラは、テンプレート関数を呼び出すときに指定したパラメータタイプを表示しなくてもよいし、指定されていない場合、コンパイラは関数パラメータリストから解析タイプを行うので、$2の呼び出し形式はfunc(66,'T')に相当します.クラステンプレートでは許可されていません.したがって、$2のパラメータタイプは関数テンプレートのフル特化バージョンと一致し、コンパイラはテンプレートのフル特化バージョンを定義し、プログラムによって呼び出され、2文が出力され、$3は関数テンプレートのリロード形式との一致が通常のテンプレートよりも高いため、#4文が呼び出され、出力される.
上の関数のテンプレート部分のプログラム出力:
以上、模版の特化問題についての浅談ですが、問題があれば、指摘して、共に進歩してください.
まず次のテンプレートを見てみましょう
#include
//
template
class Base{
private:
T1 n1;
T2 n2;
public:
Base(T1 n1_t,T2 n2_t):n1(n1_t),n2(n2_t){}
void show()const{
std::cout << "#1:" << n1 << "," << n2 << std::endl;
}
};
//
template
class Base{
private:
char n1;
T2 n2;
public:
Base(char n1_t,T2 n2_t):n1(n1_t),n2(n2_t){}
void show()const{
std::cout << "#2:" << n1 << "," << n2 << std::endl;
}
};
//
template <>
class Base{
private:
double n1;
double n2;
public:
Base(double n1_t,double n2_t):n1(n1_t),n2(n2_t){}
void show()const{
std::cout << "#3:" << n1 << "," << n2 << std::endl;
}
};
int main(){
using namespace std;
Base s1('A',11); //
Base s2(20,20); //
Base s3(13.5,26.5); //
s1.show();
s2.show();
s3.show();
return 0;
}
一般的なテンプレートの定義形式に詳しいと思いますが、ここではテンプレートの特化時の定義形式についてお話しします.
テンプレートの特化とは何でしょうか.どんな役割がありますか.テンプレートの特化はテンプレートの具体化とも呼ばれ、テンプレートパラメータが特定のタイプで具体的に実現されることを指す.テンプレートのインスタンス化時にテンプレートの優先度を合わせるために使用されます.
テンプレートでの優先順位の一致:テンプレートのフル特化>テンプレートの偏特化>通常のテンプレート
テンプレート偏特化は、既存のテンプレートに対して部分的に具体化され、元のテンプレートパラメータリストのいくつかの汎用パラメータを特定のタイプに指定するために使用されます.上記コードでは、テンプレートパラメータリストのT 1を特定のタイプのcharとして指定する、2番目のテンプレートパラメータT 2は指定されていない、クラステンプレートをインスタンス化する必要がある場合、指定したテンプレートの1番目のパラメータタイプがcharである場合、通常のテンプレートよりもマッチング度が高いため、このオフセットバージョンを優先してインスタンス化するもちろん、これは、特定のフル特化バージョンがない場合、フル特化が一致し、偏特化や通常のテンプレートよりも優先度が高いためです.
上記のコードに示すように、s 1オブジェクトのインスタンス化にはcharとintタイプが1つ提供され、1つ目のタイプはBaseテンプレートのオフセットとちょうど一致するので、このオフセット化バージョンを優先してオブジェクトをインスタンス化するので、s 1.show()は#2の文を出力します.
s 2オブジェクトは2つのintタイプを提供し、これはテンプレートのフル特化バージョンと偏特化バージョンと一致しないため、通常のテンプレートを用いてインスタンス化する.show()ですので#1の文を出力します.
s 3オブジェクトは2つのdoubleタイプを提供し、これはテンプレートのフル特化と一致するので、このテンプレートのフル特化バージョンを用いてインスタンス化する、s 3.show()は#3の文を出力します.
上のコードの実行後の出力:
#2:A,11
#1:20,20
#3:13.5,26.5
関数テンプレートの定義形式はクラステンプレートと似ていますが、現在の関数テンプレートではオフセットは許可されず、フル特化のみが許可されていますが、関数テンプレートは関数テンプレートの再ロードによって「オフセット」を実現できます.コード:
//
template
void func(const T1& a , const T2& b){
std::cout << "#1:" << a << "," << b << std::endl;
}
//
template<>
void func(const int& a, const char& b){
std::cout << "#2:" << a << "," << b << std::endl;
}
/*
// !
template
void func(const double& a,const T2& b){
std::cout << "#3:" << a << "," << b << std::endl;
}
*/
// “ ”
template
void func(const double& a,const T2& b){
std::cout << "#4:" << a << "," << b << std::endl;
}
int main(){
using namespace std;
func(13,20); //$1
func(66,'T'); //$2
func(96.5,10); //$3
return 0;
}
関数テンプレートの定義形式はクラステンプレートと似ているが、関数テンプレートには偏特化は存在せず、全特化のみであるため、クラステンプレート方式で偏特化バージョンを宣言するとコンパイラは許されない.もちろん,関数テンプレートの重荷による変相による「偏特化」効果は可能であるが,関数テンプレートに偏特化があるわけではない.上記のコード$1関数では、2つのintタイプを関数テンプレートのタイプパラメータとして使用します.一致する特化バージョンは存在しないため、コンパイラは通常の関数テンプレートを使用して関数を定義し、プログラムに呼び出され、$2が1文を呼び出して出力します.ここまで$2は他のテンプレート関数呼び出し形式とは異なり、テンプレートパラメータのタイプを指定していないことがわかりました.これも許可されています(関数テンプレートのみ)コンパイラは、テンプレート関数を呼び出すときに指定したパラメータタイプを表示しなくてもよいし、指定されていない場合、コンパイラは関数パラメータリストから解析タイプを行うので、$2の呼び出し形式はfunc(66,'T')に相当します.クラステンプレートでは許可されていません.したがって、$2のパラメータタイプは関数テンプレートのフル特化バージョンと一致し、コンパイラはテンプレートのフル特化バージョンを定義し、プログラムによって呼び出され、2文が出力され、$3は関数テンプレートのリロード形式との一致が通常のテンプレートよりも高いため、#4文が呼び出され、出力される.
上の関数のテンプレート部分のプログラム出力:
#1:13,20
#2:66,T
#4:96.5,10
以上、模版の特化問題についての浅談ですが、問題があれば、指摘して、共に進歩してください.