C++テンプレートと汎用プログラミングについて

7818 ワード

一、汎用プログラミング
STLは汎用プログラミングです.汎用プログラミングは、データ型とは独立したコードを定義することを目的としています.オブジェクト向けプログラミングはプログラミングのデータ面に注目し,汎用プログラミングはアルゴリズムに注目する.それらの間の共通点は抽象的で再利用可能なコードを作成することですが、彼らの理念は決して同じではありません.C/C++は静的プログラミング言語で、コードを実行可能なバイナリ実行可能プログラムに翻訳して実行する必要があります.コンパイルが完了すると変更できません(データ型が確定すると変更できませんので、データ型ごとにアルゴリズムを作成します).
  • C言語での高速ソート:
  • void qsort(void *base, size_t nmemb, size_t size,int(*compar)(const void *, const void *));
  • C++はテンプレートのプログラミング方法を提供して汎用プログラミングの問題を解決して、彼の解決の構想は、プログラマーはまず1部の“套路コード”を編纂して、それから呼び出しの時にコンパイラは呼び出しの時のパラメータによって更にこのようなデータ型のために1部の専属コードを生成します.

  • 二、反復器
    テンプレートは、アルゴリズムを格納されたデータ型から独立させ、反復器はアルゴリズムを使用するコンテナ型から独立させることができます.では、反復器はいったい何なのでしょうか.例を挙げると、ソート関数sort()を定義して配列をソートすると、sort()は配列全体を遍歴し、ソートする必要があります.チェーンテーブルをソートする場合は、チェーンテーブル全体をソートする新しいsort()関数を再定義する必要があります.詳細から言えば、配列とチェーンテーブルのsort()関数は間違いなく異なり、1つは下付きで、1つはnode->nextである.しかし、広義には、データ型コンテナ全体を遍歴し、メンバーデータを順次比較することでソートの効果が得られ、メカニズムは同じです.汎用プログラミングは、同じsort関数を使用して異なるコンテナをソートすることを目的としています.すなわち、関数はデータ型だけでなく、データ型を格納するコンテナデータ構造とは独立しており、テンプレートはコンテナに格納されるデータ型の汎用表現を提供し、反復器はコンテナの値を遍歴する汎用表現です.
    1.反復器が備えるべき機能:
  • 反復器は、参照された値にアクセスできるように、参照を解除することができる.すなわち、pが反復器である場合、*pは参照された値にアクセスすることができる.ポインタに似ているのではないでしょうか(脱出
  • 反復器間で付与可能、p=q
  • 反復器間で比較でき,p==q,p!=q
  • 反復器を使用して、すべての要素、p+、++p
  • を巡回することができる.
    2.反復器タイプ
    反復機能
    入力反復
    しゅつりょく反復器
    じゅんほうこう反復器
    にほうこう反復器
    ランダムアクセス反復
    リファレンス読み込み解除
    あります
    なし
    あります
    あります
    あります
    リファレンス書き込みの解除
    なし
    あります
    あります
    あります
    あります
    固定および繰り返し可能なソート
    なし
    なし
    あります
    あります
    あります
    ++i,i++
    あります
    あります
    あります
    あります
    あります
    - -i,i- -
    なし
    なし
    なし
    あります
    あります
    i[n]
    なし
    なし
    なし
    なし
    あります
    i+n
    なし
    なし
    なし
    なし
    あります
    i-n
    なし
    なし
    なし
    なし
    あります
    i +=n
    なし
    なし
    なし
    なし
    あります
    i -=n
    なし
    なし
    なし
    なし
    あります
    反復器の機能強度は左から右に順次増加した.
    3.反復器の定義:
    type::iterator p;
    //vector 
    vector<int>::iterator p1;
    //list
    list<double>::iterator p2;

    反復器の遍歴
    std::vector<int> v(5);
    std::vector<int>::iterator p = v.begin();//begin                
    while(p != v.end())//end                    
    {
        p++;
    }
    

    三、テンプレートの文法
    template T,typename Class>
    T func(T num1,T num2)
    {
        ...
    }
  • Tはテンプレートのタイプパラメータと呼ばれ、他の名前を付けることができ、関数呼び出し時の任意のタイプのパラメータ
  • を指す.
  • テンプレートのタイプは任意ですが、テンプレート関数で使用する演算子をサポートする必要があります.したがって、テンプレートは万能の
  • ではありません.
    四、関数テンプレートの使用
  • 1、テンプレートのインスタンス化:コンパイラは関数テンプレートを一例にコンパイルするのではなく、呼び出し時のパラメータに基づいてインスタンス化(さらにバイナリ命令を生成)
  • を行う.
  • 2、テンプレートを使用する場合のみインスタンス化:テンプレートは呼び出し時にのみインスタンス化されるため、テンプレートのコンパイルが正しいことはコードに問題がないことを意味せず、多くのエラーが呼び出し時に発生します.
  • 3、二次コンパイル:1回目はテンプレートの構文をチェックし、2回目のコンパイル時に呼び出しパラメータに基づいてテンプレートをインスタンス化し、演算子がこのタイプをサポートしているかどうかをチェックします.

  • 五、関数テンプレートの暗黙的な推定
  • aは、関数テンプレートを用いる場合、パラメータの種類に応じてテンプレートのパラメータ
  • を推定することができる.
  • bは、関数テンプレートが関数呼び出し時のパラメータからテンプレートパラメータを推定できない場合に使用して明示的に指定することができる.
  • c、関数テンプレートパラメータはデフォルト値の1、デフォルト値を右に2、C++標準サポート:-std=c++0 x
  • 六、関数テンプレートの重荷
  • 1、同じフォーマットの通常関数と関数テンプレートは同時に存在してもよく、呼び出し時にパラメータタイプが通常関数と同じであれば、通常関数が優先的に呼び出されます.(呼び出し時に関数名に<>呼び出しテンプレート関数を付けることができる)
  • 2、通常関数は、同じ整数型、または浮動小数点型でタイプ変換できますが、変換呼び出し通常関数の優先度はテンプレート関数のインスタンス化よりも低くなります.
  • 3、関数テンプレートはタイプアップ(int->short/加constなど)も可能ですが、同フォーマットの一般関数もタイプアップを行うと、一般関数が優先的に呼び出されます.

  • 七、クラステンプレート
  • a、クラステンプレートの構文
  • template...>
    class classname
    {
        C c;
    public:
           A func(B b);
    }

     注意:typenameも引き続き使用できますが、classで区別を示すことが多いです
  • b、クラステンプレートの使用クラステンプレートはインスタンス化されなければ使用できません.2回のコンパイルも必要です.1回目はクラステンプレートを「汎用プレート」にコンパイルします.このプロセスは文法をチェックするためです.2回目はインスタンス化パラメータに基づいてクラスを生成し、このクラスを使用してオブジェクトを作成します.クラステンプレートを使用してオブジェクトclassname a;
  • を作成します.
  • c、クラステンプレートパラメータは暗黙的な推定をサポートせず、インスタンス化
  • を表示する必要がある.
  • d、静的メンバーの定義構文
  • template<class T>
    class classname
    {
        T data;
        static T num;
        ....
    }
    template <class T>
    T className<T>::num = 10;

    静的メンバーは、クラステンプレートがインスタンス化された後に定義される必要があります.各インスタンス化されたクラスには静的メンバーがあり、これらの同じTのクラスは静的メンバーを共有します.
  • e、ネストインスタンス化
  • MyStackint>> stack;

    八、クラステンプレートの特化(重荷)
  • 特化:クラステンプレートに特殊なタイプがあって処理できない場合、このような特殊なタイプのためにクラスを個別にインスタンス化することができ、このような個別の実装をテンプレートの特化と呼ぶ.
  • 全クラスの特化:クラスのフォーマットに従ってクラスを完全にもう一度実現する.
  • template <> class classname //  char*
    {
    ...
    };

      メンバーの特化:指定したタイプに特殊なメンバー関数を指定します.
    template<>     className ::special_func()
    {
        ...
    }

    ジルコニア局所特化:同じ局所特化があれば二義性をもたらす
    template<class A,class B> class N 
         {public:N(void){cout <<"1"<template<class A> class N {public:N(void){cout <<"2"<template<class A,class B> class N//  の  と
    {public:N(void){cout <<"2"<template<class A> class Nshort> 
    {public:N(void){cout <<"3"<template<class A> class N{public:N(void){cout <<"4"<template<class A,class B> class N{public:N(void){cout <<"5"<

    九、クラステンプレートのパラメータ
  • 1、クラステンプレートのパラメータにはデフォルト値があります注意:クラステンプレートのデフォルト値を使用する場合、<>は省略できません.空いていてもいいですが、
  • と書かないわけにはいきません.
  • 2、クラステンプレートの後のパラメータは、前のパラメータ
  • を呼び出すことができる.
  • 3、通常の数値はクラステンプレートをインスタンス化することができ、彼は類似変数の形で存在しなければならない.注記:
  • をインスタンス化できるのは定数のみです.