C++におけるTemplateの使い方


テンプレート(Template)
C++プログラミング言語でパラメータとしてタイプを採用したプログラミングを指し、汎用プログラミングをサポートする.C++の標準ライブラリは、STLやIO Streamのようなテンプレートの観念を結合した多くの有用な関数を提供しています.
関数テンプレート
関数テンプレートは、ファミリー関数を定義します.
//template1.cpp #include 

template<typename T> void swap(T &a, T &b) {

T tmp{a}; a = b;

b = tmp;

}

int main(int argc, char* argv[])

{

int a = 2; int b = 3;

swap(a, b); //       

std::cout << "a=" << a << ", b=" << b << std::endl;

double c = 1.1; double d = 2.2; swap(c, d);std::cout << "c=" << c << ", d=" << d << std::endl;return 0;

}

関数テンプレートのフォーマット:
template<parameter-list> function-declaration

関数テンプレートは形式的に2つの部分に分けられます:テンプレート、関数.関数の前にtemplateを付けると関数テンプレートになるので、関数の各種修飾(inline、constexprなど)はtemplateの前ではなくfunction-declarationに加える必要があります.のように
template

inline T min(const T &, const T &);

上のswap関数テンプレートでは、タイプパラメータが使用されています.関数テンプレートは契約のようなもので、その契約を満たすタイプはテンプレートの実パラメータとして使用できます.契約は関数実装において,テンプレート実パラメータがサポートする様々な操作である.上
swapにおけるTが満たすべき契約は,コピー構造と付与をサポートすることである.
C++の関数テンプレートは本質的に関数のリロードであり、汎用型はプログラマーの仕事を簡略化し、これらのリロードをコンパイラで完成させるだけである.
関数テンプレートは関数ではありません
関数テンプレートは、関数ではなくファミリー関数を定義するために使用されます.C++は強いタイプの言葉です
すなわち,Tの具体的なタイプを知らない前に,swapが占有するスタックサイズ(パラメータスタック,局所変数)を特定することはできず,また関数体におけるTの各種操作がどのように実現されるかも分からず,具体的な関数を生成することはできない.具体的に
タイプがTを置き換えると、関数テンプレートのインスタンス化と呼ばれる特定の関数が生成されます.main関数でswap(a,b)を呼び出すと、コンパイラはこのときTがintであると推定し、コンパイラはint版のswap関数を生成して呼び出す.したがって、通常の関数に比べて、関数テンプレートは具体的な関数を生成するステップを多くします.もし私たちがただ編んだだけなら
関数テンプレートが書かれていますが、どこでも使用されません(明示的にインスタンス化されていません).コンパイラは関数テンプレートのコードを生成しません.関数テンプレートのインスタンス化は、暗黙的インスタンス化と明示的インスタンス化に分けられます.
暗黙的インスタンス化
swapを例にとると、mainでswap(a,b)を呼び出すと、暗黙的なインスタンス化(implicit instantiation)が発生する.関数テンプレートが呼び出され、以前に明示的なインスタンス化がなかった場合、関数テンプレートの暗黙的なインスタンス化が発生します.テンプレートの実パラメータが呼び出しの文脈から導出できる場合は、提供する必要はありません.効率が低い.
//template2.cpp #include

template void print(const T &r) {

std::cout << r << std::endl;

}

int main() {

//      print(int) print(1);

//     print(char) print<>('c');

//         ,         print(double) print(1);

return 0;

}