C++テンプレート、特化、偏特化

4818 ワード

前言
C++テンプレートの特化と偏特化は、他の人にとって、もう新しいものではありませんが、私にとって、確かに私の盲区で、その日グループの中でこの問題を討論して、自分はこの部分に対して確かに掌握していないで、また《STLソースコードの剖析》の本の中で連想して、これに対しても紹介があります.だから、今日はこれについて詳しくまとめて、忘れないようにします.
C++テンプレート
C++テンプレートの特化と偏特化といえば、C++のテンプレートについて簡単に話さなければなりません.強いタイプのプログラム設計は、論理構造が同じで具体的なデータ型が異なるオブジェクトのためにモードが一致するコードを記述させ、その共通性を抽出することができず、プログラムの拡張とメンテナンスに明らかに不利であることを知っています.C++テンプレートが誕生しました.C++のテンプレートは、論理構造が同じデータオブジェクトの共通動作の定義を提供します.これらのテンプレート演算オブジェクトのタイプは、実際のデータ型ではなく、パラメータ化されたタイプです.C++のテンプレートはクラステンプレートと関数テンプレートに分けられます.
#include 
using namespace std;

template 
class TClass
{
public:
     // TClass     

private:
     T DateMember;
};
template 
T Max(const T a, const T b)
{
     return  a > b ? a : b;
}

テンプレート特化
必要に応じて、特定のタイプに対してテンプレートを特化する、いわゆる特殊な処理が必要になる場合がある.たとえば、次のコードがあります.
#include 
using namespace std;

template 
class TClass
{
public:
     bool Equal(const T& arg, const T& arg1);
};

template 
bool TClass::Equal(const T& arg, const T& arg1)
{
     return (arg == arg1);
}

int main()
{
     TClass obj;
     cout<

クラスには、2つのパラメータが等しいかどうかを比較するためのEqualメソッドが含まれています.上のコードの実行には何の問題もありません.しかし、実際の開発では絶対にこのように書いてはいけないと思ったことはありませんか.floatタイプやdoubleのパラメータについては、決して「=」記号を直接使って判断することはできません.したがって、floatまたはdoubleタイプについては、次のような特殊な処理が必要です.
#include 
using namespace std;

template 
class Compare
{
public:
     bool IsEqual(const T& arg, const T& arg1);
};

//      template    ,     float 
template <>
class Compare
{
public:
     bool IsEqual(const float& arg, const float& arg1);
};

//      template    ,     double 
template <>
class Compare
{
public:
     bool IsEqual(const double& arg, const double& arg1);
};

template 
bool Compare::IsEqual(const T& arg, const T& arg1)
{
     cout<::IsEqual"<::IsEqual(const float& arg, const float& arg1)
{
     cout<::IsEqual"<::IsEqual(const double& arg, const double& arg1)
{
     cout<::IsEqual"< obj;
     Compare obj1;
     Compare obj2;
     cout<

テンプレートへんこう
テンプレートの特化についてまとめました.テンプレートの偏特化は?偏特化とは、別のtemplate定義式を提供し、それ自体がtemplatizedであることを意味する.すなわち,templateパラメータのさらなる条件制限に対して設計された特化バージョンである.このような偏特化の応用はSTLで随所に見られる.例:
template 
struct iterator_traits
{
     typedef typename _Iterator::iterator_category iterator_category;
     typedef typename _Iterator::value_type        value_type;
     typedef typename _Iterator::difference_type   difference_type;
     typedef typename _Iterator::pointer           pointer;
     typedef typename _Iterator::reference         reference;
};

// specialize for _Tp*
template 
struct iterator_traits<_tp> 
{
     typedef random_access_iterator_tag iterator_category;
     typedef _Tp                         value_type;
     typedef ptrdiff_t                   difference_type;
     typedef _Tp*                        pointer;
     typedef _Tp&                        reference;
};

// specialize for const _Tp*
template 
struct iterator_traits 
{
     typedef random_access_iterator_tag iterator_category;
     typedef _Tp                         value_type;
     typedef ptrdiff_t                   difference_type;
     typedef const _Tp*                  pointer;
     typedef const _Tp&                  reference;
};

見ましたか?これがテンプレートの偏特化であり、テンプレートの特化との違いは、テンプレートの特化後、実際にはそれ自体がtemplatizedではなく、偏特化してもtemplatizedが付いていることである.実際の例を見てみましょう
#include 
using namespace std;

//      
template 
class TestClass
{
public:
     TestClass()
     {
          cout<
class TestClass
{
public:
     TestClass()
     {
          cout<
class TestClass
{
public:
     TestClass()
     {
          cout< obj;
     TestClass obj1;
     TestClass obj2;

     return 0;
}

出力結果については、ここでは書かないので、試してみてください.
特化と偏特化の呼び出し順序
テンプレート、テンプレートの特化、テンプレートの偏特化が存在する場合、コンパイラはコンパイル段階でマッチングする場合、どのように選択しますか?哲学の角度から言えば、まず最も特殊なことを世話しなければならなくて、それからやっと特殊で、最後に最も普通です.コンパイラが選択するのも尊従の道理だ.上の例からも分かるように、例を挙げて説明しません.