CPP-テンプレート小学校


タイトル:テンプレート小学校の
DATE:2019年3月18日午後八時37分56秒
タグ:CPP
カテゴリー:CPPの
TOC:trueに


ジェネリックプログラミング

コンパイラは、異なるタイプに応じて金型を使用してコードを生成するように、金型にコンパイラーに指示します。

ジェネリックプログラミング:タイプに関係なく、一般的なコードを書くには、コードの再利用の手段です。テンプレートは、ジェネリックプログラミングの基本です。

関数テンプレート

関数テンプレートは、関数のファミリーを表し、タイプに関係なく、使用時にパラメータ化された関数テンプレートは、引数の型の種類に応じて関数の特定のバージョンを生成します。

関数テンプレートの形式

template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}

template<typename T>	// 模板头
void Swap(T& left,  T& right)
{
    T temp = left;
    left = right;
    right = temp;
}

⚠️注:型名キーワードがテンプレートパラメータを定義するために使用され、あなたがクラスを使用することができます(覚えている:あなたが代わりにクラスの構造体を使用することはできません)

原則として関数テンプレート

テンプレート自体は関数、関数の特定の種類の特定の用途を製造する金型のコンパイラではない設計図、です。実際には、我々がされている必要がありますので、テンプレートは、コンパイラに繰り返し物事を行うことです。

コンパイル時にコンパイラ、テンプレート機能を使用して、推定するコンパイラーのニーズがコール用渡された引数の型のタイプの対応する機能を生成します。

⚠️注:ここでは、それを理解しています。スワップ機能は、上記着信INTダブル最終呼が実際には二つの機能をコンパイルされるように、このアドレスを確認する機能を表示又は印刷することによってアセンブリコードとすることができるような呼び出し。

関数テンプレートのインスタンス化

関数テンプレートと呼ばれる関数パラメータの異なるタイプのテンプレートを使用する場合は、インスタンス化されます。:テンプレートパラメータの例としては、に分かれて暗黙的にインスタンス化明示的にインスタンス化

暗黙的の例

テンプレートパラメータに基づいて実際の型引数を推論コンパイラをしてみましょう。

template<class T>
T Add(const T& left, const T& right)
{
    return left + right;
}
int main() 
{
    int a1 = 10, a2 = 20;
    double d1 = 10.0, d2 = 20.0;
    Add(a1, a2);
    Add(d1, d2);
    /*
      该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型 通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错
      注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
      Add(a1, d1);
    */
  
    // 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化 
  	Add(a, (int)d);
    return 0;
}

表示の例

明示的な例:テンプレートパラメータは、<>内に関数名の実際の型を指定します。

型が一致しない場合、コンパイラは、変換が成功した場合、コンパイラはエラーではありません、暗黙の型変換を試みます。

Add<int>(a, b);

原則テンプレートパラメータをマッチング

1.レイジー

関数は、同じ名前が存在と非テンプレートとテンプレート関数とすることができるだけでなく、関数テンプレートは、非テンプレート関数としてインスタンス化することができます。

コンパイラは、ハハ、また非常に「怠惰」です。コンパイラ:「ここでは、私はカバーあなたに関数を生成し、あなたを推測与えることはありません、持っています。」

// 非模板函数
int Add(int left, int right) 
{
    return left + right;
}

// 通用加法函数 template<class T>
T Add(T left, T right)
{
    return left + right;
}
void Test()
{
    Add(1, 2); // 与非模板函数匹配,编译器不需要特化
		Add<int>(1, 2); // 调用编译器特化的Add版本 
}

2.勤勉

他の条件が同じであれば、非テンプレート関数と同じ名前の関数テンプレートのために、非優先の動員は、テンプレートからインスタンスを生成せずにテンプレート関数を呼び出すとき。テンプレート関数がより良い一致を生成することができた場合は、テンプレートを選択します。

Add(1, 2.0);
// 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数

3.けち

テンプレート機能は、自動型変換を許可していませんが、一般的な機能は、型変換を自動化することができます。

クラステンプレート

フォーマット

class 类模板名
{
    // 类内成员定义 
};

⚠️注:もう一つ注意すべきは、ハに呼ばれています!

注意:
  Date类:
    类名 Date 类型 Date
  模板类:
    类名 Vector 类型 Vector<int>

?栗:ベクトルの動的なシーケンステーブル

template<class T> class Vector
{
public :
    Vector(size_t capacity = 10)
        : _pData(new T[capacity])
        , _size(0)
        , _capacity(capacity)
    {}
    // 使用析构函数演示:在类中声明,在类外定义。 ~Vector();
    void PushBack(const T& data)
    {
        // _CheckCapacity();
        _pData[_size++] = data;
    }
    void PopBack()
    {
        --_size; 
    }
    size_t Size()
    {
        return _size;
    }
    T& operator[](size_t pos)
    {
        assert(pos < _size);
        return _pData[pos];
    }

private:
    T* _pData;
    size_t _size;
    size_t _capacity;
};

⚠️注:

  • 過負荷演算子は[]、インターフェースはサイズ的に類似配列アクセスのプライベートメンバーを達成するために実装されています。

  • テンプレートクラスは、外部関数に基づいて定義されている場合、テンプレートパラメータリストを追加する必要があります

    template <class T>
    Vector<T>::~Vector()
    {
        if(_pData) 
        {
        		delete[] _pData;
        }
    }
    

インスタンス化

関数テンプレートのインスタンス異なるクラステンプレートのインスタンス化の必要性のクラステンプレートのインスタンス化<>に続いて、クラステンプレート名、その後することができ、<>のインスタンスに入力し、クラステンプレートクラスの本当の名前ではなく、インスタンス化その結果、実際のクラスです。

Vector<int> s1;
s1.PushBack(1);
s1.PushBack(2);
s1.PushBack(3);
Vector<double> s2;
s2.PushBack(1.0);
s2.PushBack(2.0);
s2.PushBack(3.0);

for(size_t i = 0; i < s1.Size(); ++i)
{
    cout<<s1[i]<<" ";
}
cout<<endl;
for(size_t i = 0; i < s2.Size(); ++i)
{
    cout<<s2[i]<<" ";
}
cout<<endl;

STLはじめに(ピットに?)

本当に、本当に、本当に便利なああ、左の轟音。

オンラインと言っている:少し学ぶためにピットに、「STLを理解していないが、あなたの意志C ++言っていません」。

STL(標準テンプレートライブラリlibaray-標準テンプレートが):C ++標準ライブラリの重要な部分であり、再利用可能なコンポーネントライブラリである、とだけでなく、
データ構造とアルゴリズムのカバーのためのソフトウェアフレームワークです。

STLのバージョン

元のバージョンの HP研究所の元のバージョンではアレクサンダー・ステパノフ、孟リーは、オープンソースの精神で、彼らは無償で、商用のコードを使用して、送信、変更、コピー、誰もが任意の使用を宣言することができ、完成しました。唯一の条件は、また、同じことを行うオープンソースの元のバージョンを使用する必要があります。HPバージョン- STLの実装の祖先のすべてのバージョン。

PJ版比較的低い可読性、むしろ奇妙なシンボル名:HPバージョンから継承されたPJ Plauger、によって開発されたが、欠陥を、開いているWindowsのVisual C ++を採用することができないか、変更します。

RWのバージョンは、ルージュ賃金会社によって開発されたHPバージョンから継承された、C + + Builderの用途、オープンできないか、変更、一般的な読みやすさ。

SGI版シリコングラフィックスコンピュータシステム株式会社の会社によって開発されたが、HPバージョンから継承されました。GCC(Linux)の優れたポータビリティを使用しては、開いているビューのスタイルポイントをスタイルに名前を付けるとプログラミングから、変更しても、販売することができ、読み取りは非常に高いです。

STL 6つのコンポーネント

コンテナ(コンテナ)

アルゴリズム(アルゴリズム)

イテレータ(イテレータ)

数子(Functionオブジェクト)

アダプター(アダプター)

宇宙コンフィギュレータ(アロケータ)

STLの学習の3つの段階

あなたは、賢明な、拡張することができますすることができます。

STL欠陥

  1. STLライブラリの更新が遅すぎます。これはTucao、ハエの以前のバージョンでは、C ++ 98、基本的なC ++ 03の改正の一部の真ん中で深刻でした。C ++ 11は、13年間のうち分離された、STLはさらにアップデートしました。

  2. サポートスレッドの安全性のない今STL。私たちは、自分自身の並行環境をロックする必要があります。ロックの粒度は比較的大きいです。

  3. 内部の複雑な結果として効率のSTLの極度の追求、。そのような抽出、抽出イテレータの種類として。

  4. STLは、それがコードの複数のコピーを生成します、このようなベクトル/ベクトル/ベクトルの使用などのコード肥大化の問題を、使用することになり、当然のことながら、テンプレート構文の結果そのものです。


公開された73元の記事 ウォン称賛90 ビュー40000 +

おすすめ

転載: blog.csdn.net/Hanoi_ahoj/article/details/88660481