c++復習の関数テンプレートtemplate(10)


関数テンプレートtemplate
関数テンプレートは、intやdoubleなどの特定のタイプで置き換えられる汎用的な関数記述です.タイプをパラメータとしてテンプレートに渡すことで、コンパイラにそのタイプの関数を生成させます.このプログラミング方式は汎用プログラミングとも呼ばれる.タイプはパラメータで表されるため、テンプレート特性はパラメトリックタイプとも呼ばれることがある.パラメータテンプレートを使用すると、任意のタイプの方法で関数を定義できます.たとえば、交換テンプレートを作成できます.
template<typename Anytype>//   template
void Swap(Anytype &a, Anytype &b)
{
    Anytype temp;
    temp = a;
    a = b;
    b = temp;
}

最初の行では、テンプレートを作成し、タイプをAnytypeと命名することを示します.キーワードtemplateとtypenameは、typenameの代わりにキーワードclassを使用できない限り必須です.例外として、カッコ<>を使用する必要があります.タイプ名は任意に選択できます(T?)テンプレートは関数を作成しません.コンパイラに関数の定義方法を教えるだけです.intの関数を交換する必要がある場合、コンパイラはテンプレートモードでこのような関数を作成し、Anytypeの代わりにintを使用します.テンプレート関数を使用する場合は、ファイルの開始位置にテンプレート関数のプロトタイプを指定し、main()の後にテンプレート関数の定義を指定します.
#include 
template<typename T>
void Swap(T &a, T &b);

int main()
{
    using namespace std;
    int i = 10;
    int j = 20;
    Swap(i, j);

    double x = 12.2;
    double y = 34.6;
    Swap(x, y);

    getchar();
    return 0;
}

template<typename T>
void Swap(T &a, T &b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}

上記のプログラムを実行すると、コンパイラは最終的に2つの独立した関数定義(すなわち、インラインではなく、通常の関数の宣言定義と同じ)を生成します.これらの関数を手動で定義したように、最終的なコードにはテンプレートは含まれず、プログラムのために生成された実間関数のみが含まれます.
1リロードされたテンプレート
通常の関数定義をリロードするようにテンプレート定義をリロードすることができ、リロードされたテンプレートの関数フィーチャーラベルは異なる必要があります.
template 
void Swap(T &a, T &b);

template 
void Swap(T *a, T *b, int n);//            ,         

すべてのテンプレートパラメータがテンプレートパラメータタイプでなければならないわけではありません.int nはテンプレートパラメータタイプではありません.
2テンプレートの限界
作成したテンプレートでは、いくつかのタイプを処理できない場合があります.
3明示的な具体化
C++98には、次のような方法があります.
  • は、所与の関数名について、非テンプレート関数、テンプレート関数、および明示的に特定されたテンプレート関数、およびそれらのリロードバージョンを有することができる.
  • の明示的に具体化されたプロトタイプおよび定義はtemplate<>で始まり、名前でタイプを示す必要があります.
  • 具体化は、テンプレート関数ではなく、従来のテンプレートよりも優先される.

  • “` c++ //non template function prototypr void Swap(job &, job &); //template prototype template void Swap(T &a, T &b); //explicit specialization for the job type template<>void Swap(job &a, job &b);
    4インスタンス化と具体化
    コードに関数テンプレートを含めること自体は、関数定義を生成しません.関数定義を生成するためのスキームにすぎません.コンパイラがテンプレートを使用して特定のタイプの生成関数を定義する場合、テンプレートインスタンス(instantiation)が得られます.テンプレートは関数定義ではありませんが、intを使用するテンプレートの例は関数定義です.このインスタンス化方式を暗黙的インスタンス化(implicit instantiation)と呼ぶ.c++は明示的なインスタンス化を可能にし、直接コマンドコンパイラは特定のインスタンスを作成します.
    template void Swap(int &, int &);
    

    暗黙的インスタンス化、明示的インスタンス化、および明示的インスタンス化は、一般的な説明ではなく、特定のタイプの関数定義を使用することと総称される.
    5コンパイラはどの関数バージョンを使用するかを選択します.