クラステンプレートの使用と詳細


私たちは異なるタイプのパラメータのクラスを書くとき、特にコンテナクラスでは、保存したいオブジェクトのタイプが異なる以外に、コードが同じであることを望んでいます.このとき、私たちは汎型のクラスを望んでいます.私たちは毎回実現するのではなく、具体的なタイプをパラメータの形式で伝えることができます.
c++のクラステンプレートは、汎用的なクラス宣言を生成するのに良い方法を提供します.これもコード再利用の重要な一部です.
まず、テンプレートクラスをどのように定義しますか.
template
キーワードtemplateは、テンプレートを定義するコンパイラに伝えます.括弧の内容はパラメータリストに相当し,キーワードclassは変数のタイプ名,Typeは変数の名前と見なす.
もちろんclassを使用することはクラスのみをパラメータとすることを意味するわけではありません.これはTypeが一般的なタイプ説明子であることを示しています.テンプレートのインスタンス化では、特定のタイプを使用して置き換えることになります.また、classの代わりにtypenameを使用することもできます.
template
<span style="font-size:18px;">template <class Type>
class Stack{
private:
     Type items[10];
     int top;
public:
     Stack();
     bool push(const Type & item);
...
};

template <class Type>    //              
Stack<Type>::Stack(){    //            
     top = 0;
}
template <class Type>
 bool Stack<Type>::push(const Type & item){
...
}</span>

重要な概念は次のとおりです.
テンプレートはクラスでもメンバー関数でもありません.クラスとメンバー関数の生成方法を説明するc++コンパイラ命令にすぎません.テンプレートの具体的な実装は、インスタンス化と具体化によって行われる.
テンプレート情報は一般的にヘッダファイルに格納され、使用時にヘッダファイルが含まれます.
次に、テンプレートクラスを使用する方法について説明します.パラメータとして特定のタイプのオブジェクトを宣言する必要があります.
例えば、Stackst;   Stack st2;
Intを使用してTypeを置き換え、doubleを使用してTypeを置き換えます.
タイプパラメータを割り当てるのはタイプのみで、数値ではありません.必要なタイプを表示する必要があります.
テンプレートクラスの拡張:
1、テンプレート内の非タイプパラメータの使用
template
キーワードclassはTをタイプパラメータ,intはnのタイプをIntとし,このパラメータを非タイプパラメータ(式パラメータ)と呼ぶ.
式パラメータにはいくつかの制限があります.式パラメータは、整数、列挙、参照、ポインタです.テンプレートコードは、パラメータの値を変更したり、パラメータのアドレスを使用したりすることはできません.例えばn+,&nなどです.
2、テンプレートの多機能性
再帰使用テンプレート:配列テンプレートArrayの場合、Array,10>twodee;
これにより、10個の要素を含む配列が得られ、各要素は5個のInt要素を含む配列である.
テンプレートには、templateという複数のタイプのパラメータが含まれます.
デフォルトタイプパラメータテンプレート:templateclass topo;
インスタンス化時にT 2を省略すると、コンパイラはintを使用します.
テンプレートの具体化:
具体化は暗黙的にインスタンス化し、インスタンス化を表示し、具体化を表示し、部分的に具体化することができます.
1、暗黙的なインスタンス化
必要なタイプを指定し、1つ以上のオブジェクトを宣言します.主な目的はオブジェクトの作成です.
pt = new Array;
コンパイラはクラス定義を生成し、定義に基づいてオブジェクトを作成します. 
2、インスタンス化を表示
キーワードtemplateを使用して、クラスを宣言するために必要なタイプを指定します.
template class Array;
オブジェクトは作成されず、クラス宣言のみが生成されます.
3、具体化表示
特定のタイプの定義です.汎用定義テンプレートとは異なり、特定の定義を持つテンプレート
template <> class Array(const char *) {...};
これはchar*タイプ専用のテンプレートです.
コンパイラは、インスタンス化時に、インスタンス化テンプレートと汎用テンプレートがインスタンス化と一致する場合に、インスタンス化テンプレートを優先的に使用するという原則に従います.
4、部分具体化
タイプパラメータのいずれかに特定のタイプを指定します.
template class Pair {...};
キーワードtemplateの後の<>宣言には具体化されていないタイプのパラメータがありますが、空の場合は表示具体化、
template <> class Pair {...};
複数のテンプレートを選択できる場合、コンパイラは最も具体化されたテンプレートを使用します.
テンプレートの使用シーン:
1、テンプレートをメンバーにする
template <class T>
class Bete{
private:
    template <class V>
    class hold{
    private:
        V val;
    public:
        hold(V v = 0):val(v){ }
        void show() const {cout << val << endl;}
    };
    hold <T> q;
    hold <int > n;
public:
    beta(T t,int i):q(t),n(i){}
...
};

これはbetaテンプレートでholdメソッドを宣言し定義し、qメンバーはタイプTに基づくholdオブジェクトである.
betaテンプレートでholdメソッドを宣言すると、外部で定義するとテンプレートネストが表示されます.
tempate <class T>
class Bete{
private:
    template <class V>
    class hold;
    hold<T> q;
    hold <int> n;
...
};
template <class T>
    template <class V>
        class Bete<T>::hold{ 
        private:
            V val;
        public:
         ...
        };

2、テンプレートをパラメータとして
テンプレートには、それ自体がテンプレートであるパラメータを含めることができます.
template