tritsプログラミング技法の悟り

6364 ワード

@オリジナル文章、転載は明記してください:鏡の中の影の技術ブログから本文のリンク先:tritsプログラミング技法の悟り)URL:http://blog.csdn.net/linkpark1904/article/details/50790917
仕事の勉強が必要なので、大学院生の段階では主にプログラミング言語ですか?それともC++をメインにしていますか?どれぐらい言語を勉強していますか?途中で聞きました.一つの言語にとって、c++は確かに歴史が長いです.みんなから評価されています.いずれにしても、一つの言語が今まで生きていることには、その存在価値と意義があります.学ぶべきところもたくさんあります.
最近幸運にもSTLのソースコードの分析を読んで、設計の標準C++倉庫の大神達を拝みました.どうやってC++を使ってSTLという壮大な王国を描きますか?
本の中で偶然にSTLの中でローズマリーをどのように設計しているかを発見しました.Traitsプログラミング技法とは、C++にtypeof()が呼び出されていない不具合を補うためのものです.スクリプト言語(javascript、python...)では、変数のタイプはtypeof呼出しで取得できますが、C++の中ではできないので、いくつかの特殊な方法で補っています.
本題に戻ります.もし汎用のディエゼルを設計してもらえば、どのような共通のディエゼルもプリントできるテンプレート関数がありますか?ポインタとは*操作を提供することにほかならない.そのため、第一のカスタムディレクタのデザインは以下の通りです.
template <class T>
class MyIter{
public:
    typedef T value_type;
    T *ptr;
    MyIter(T *p = 0):ptr(p){}
    T& operator*()const{return *ptr;}
};
typedef T value_typeを用いてテンプレートタイプTが露出される.このポインタ類はコンストラクションを提供しています.*オペレータを再搭載しています.どうやって汎用のディケンサを印刷するのに関数がありますか?この関数の戻り値はどうなりますか?正しいやり方は以下の通りです.
template I>
typename I::value_type
func(I iter){
    return *iter;
}
ただし、テンプレートIはvalue_を提供しなければならない.type変数のカスタムローズマリー、コンパイラはコンパイル段階で、MyIterの実際のテンプレート値からFnc関数の戻り値の種類を導出します.このように、Fnc関数の戻り値は、私たちがカスタマイズしたローズマリーから入ってきたテンプレートパラメータの変化に従って変化します.はっきり言って、マイスターにint型が入ったら、typedef T value_typeの作用で、value_を招きます.typeはintですので、funcの戻り値はintです.全体の実行可能コードは以下の通りです.
#include 
using namespace std;

template <class T>
class MyIter{
public:
    typedef T value_type;
    T *ptr;
    MyIter(T *p = 0):ptr(p){}
    T& operator*()const{return *ptr;}
};

template <class I>
typename I::value_type
func(I iter){
    return *iter;
}

int main(){
    MyIter<int> myIter(new int(4));
    cout << func(myIter) <return 0;
}
これで完璧だと思わないでください.ここのfunc関数は私達がカスタマイズしたローズマリーしかサポートできません.つまり、ローズマリーの中でカスタムvalue_です.typeは、汎用ポインタに対してどのようにサポートされていますか?例えば、func(new int(4))のような呼び出しは、関数を使いやすくするためには、関数が様々な状況に適合することが必要です.このために私達のTraitsプログラミング技法を紹介します.テンプレートの特化(関数に似ています.再負荷)特性を利用して、中間にTraitsクラスを追加して、カスタマイズしたローズマリーと汎用ポインタをサポートします.具体的なコードは以下の通りです.
#include 

using namespace std;

//      
template <class T>
struct MyIter{
    typedef T value_type;
    T *ptr;
    MyIter(T* p = 0):ptr(p){}
    T& operator*() const{ return *ptr;}
};

//Traits    
//        
template <class T>
class Traits{
public:
    typedef typename T::value_type value_type;
};

//  ,        
template <class T>
class Traits{
public:
    typedef T value_type;
};

//  ,    const  
template <class T>
class Traits<const T*>{
public:
    typedef T value_type;
};

//    
template <class I>
typename Traits::value_type
func(I iter){
    return *iter;
}


int main(){
    MyIter< int > p(new int(8));
    const char *ptr = "abce";
    int *a = new int(9);
    cout << func(p) <cout << func(a) <cout << func(ptr) << endl;

    return 0;
}
コンパイラを利用してコンパイルを行う場合も、最初のバージョンとは違って、今回はTraitsという層で特化しました.さまざまな種類のポインタの種類に対して、異なる操作をするという考えでしょう.