• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 31  文章 - 128  trackbacks - 0
            <2006年7月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            常用鏈接

            留言簿(5)

            隨筆分類(38)

            隨筆檔案(31)

            收藏夾(4)

            College

            High School

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 55887
            • 排名 - 407

            最新評論

            • 1.?re: [yc]詳解link
            • 面試的時候面試官就問過我什么是編譯和鏈接,我說編譯就是把代碼文件生成目標文件,鏈接就是把目標文件生成可執行文件,他說不對,又問我什么是動態鏈接,還問我預編譯都做什么處理。。。都在這里找到了答案!!!!
            • --王至乾
            • 2.?re: [yc]詳解link
            • @劉偉
              我是說博主,不是叫你啊
            • --溪流
            • 3.?re: [yc]詳解link
            • 誰是石老師,我不是哈@溪流
            • --劉偉
            • 4.?re: [yc]詳解link
            • 石老師?我是溪流~
            • --溪流
            • 5.?re: [yc]詳解link
            • 期待樓主下文啊,多謝樓主了
            • --劉偉

            閱讀排行榜

            評論排行榜

            看了546@C++@Freecity之后,發覺非常有意思,由此產生一些想法

            很多時候寫一個類的時候,需要多個模版參數,例如一個遺傳算法的算法類,需要一個模版參數來指定交配方式,另一個模版參數來指定子代選擇的方式,還要一個參數來指定變異的方式。那么一般來說,這個類會寫成:

            template<class T                                                //描述問題的一個類
                    , class CrossPolicy = AvgCrossPolicy                        //雜交方式
                    , class SelectPolicy = DefaultSelectPolicy                //子代選擇的方式
                    , class VariationPolicy = ReverseVariationPolicy>        //變異方式
            class Gene
                    : private AvgCrossPolicy
                    , private SelectPolicy
                    , private VariationPolicy
            {
                    ....
            };

            這樣用戶要使用該類的時候,可以直接指定T,就行了,然而如果要指定變異方式,那么就必須把所有的參數都顯式的寫出來,很不方便

            546提供了一種有效的方法,可以讓我們僅僅指定變異參數,而不用寫出另兩個Policy
            甚至允許我們以任意的順序書寫幾個Policy參數,都不會有問題

            預備知識:
            TypeList
            一個TypeList是一個類型的容器
            template <typename Type_, typename Next_>
            struct TypeList
            {
                    typedef Type_ Type;
                    typedef Next_ Next;
            };
            這就是一個TypeList。
            看這個寫法,是不是像一個鏈表?
            首先定義一個類型來表示鏈表尾:class NullType{};
            現在一個包含了2個類型的TypeList就可以寫為:
            TypeList<T1, TypeList<T2, NullType>  >

            如何在一個TypeList中查找一個類型的子類?
            首先要有一個IsDerivedFrom<Base, T>
            這個比較簡單
            template<class Base, class T>
            class IsDerivedFrom
            {
                    struct large{char a[2];};
                    static char pred(Base*);
                    static large pred(...);
            public:
                    enum {Is = sizeof(pred((T*)0)) == sizeof(char)};
            };

            然后FindChild就容易了
            template <class List, class Base>
            struct FindChild
            {
                    template <bool IsChild>
                    struct Select
                    {
                            typedef typename List::Type Type;
                    };

                    template <>
                    struct Select<false>
                    {
                            typedef typename FindChild<typename List::Next, Base>::Type Type;
                    };

                    typedef typename Select<IsDerivedFrom<Base, typename List::Type> >::Type Type;
            };

            當然還要對一些特殊情況進行特化,例如NullType
            template <class Base>
            struct FindChild<NullType, Base>
            {
                    typedef NullType Type;
            };
            這里使用NullType來表明沒找到

            實際操作:
            首先需要給3個Policy3個基類,分別叫
            class AvgCrossPolicyBase{};
            class SelectPolicyBase{};
            class VariationPolicyBase{};
            內容為空就行了,這樣也沒有虛函數調用的開銷


            然后聲明一個類來表示默認情況:
            class DefaultPolicy{};

            定義一個宏
            #define TYPELIST_3_N(a, b, c) TypeList<a, TypeList<b, TypeList<c, NullType> > >

            下面要寫一些選擇器,用于把合適的類型選擇出來,如果沒找到,則要使用默認的類型
            template <class List, class Base, class DefaultType>
            struct Selector
            {
                    template <class RetType>
                    struct Judge
                    {
                            typedef RetType Type;
                    };
                   
                    template<>
                    struct Judge<NullType>
                    {
                            typedef DefaultType Type;
                    };
                    typedef typename Judge<typename FindChild<List, Base>::Type >::Type Type;
            };

            好啦,現在整個類的聲明可以寫為

            template<class T
                    , class CrossPolicy_ = DefaultPolicy
                    , class SelectPolicy_ = DefaultPolicy
                    , class VariationPolicy_ = DefaultPolicy     //其后的參數用戶不可指定
                    , class List = TYPELIST_3_N(CrossPolicy_, SelectPolicy_, VariationPolicy_)
                    , class CrossPolicy = typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type
                    , class SelectPolicy = typename Selector<List,  SelectPolicyBase,  DefaultSelectPolicy>::Type
                    , class VariationPolicy = typename Selector<List,  VariationPolicyBase,  ReverseVariationPolicy>::Type
                    >
            class Gene
                    : private CrossPolicy
                    , private SelectPolicy
                    , private VariationPolicy
            {
                   
                    ....
            };


            其中第4-7個參數(List,CrossPolicy,SelectPolicy和VariationPolicy)是不由用戶指定的,僅僅是為了起一個別名
            第一個參數T必須指定,然后2,3,4這3個參數就可以任意的改變順序了
            例如,可以寫Gene<T, DefaultSelectPolicy, AvgCrossPolicy>而不會有任何問題
            如果不想要最后面幾個參數的話也行,但是代碼就要稍微長一點
            而且最好在類里面進行3個typedef
            typedef typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type CrossPolicy;
            等,以便在實現的時候使用

            posted on 2006-07-24 01:06 shifan3 閱讀(1010) 評論(9)  編輯 收藏 引用 所屬分類: templateC++

            FeedBack:
            # re: 亂序Policy手法 2006-07-24 09:25 小明
            華麗是華麗,可是不實在,工程師慎用  回復  更多評論
              
            # re: 亂序Policy手法 2006-07-24 12:06 Arcrest
            靜態的多態還是有用的時候,C++ Modern Design詳解
            當然項目中的話,維護人員要求高了點。。。

              回復  更多評論
              
            # re: 亂序Policy手法 2006-07-24 12:12 Francis Arcanum
            這種東西的特點就是,不管怎么搞,也都是編譯錯誤
            而編譯錯誤怎么詭異也比運行錯誤容易解決  回復  更多評論
              
            # re: 亂序Policy手法 2006-10-22 08:42 pluskid
            T_T
            看不懂 C++ 代碼~~~
            不過,lisp 里面支持亂序參數是使用keyword來支持。例如:
            (defun foo (&key foo (bar 'default-bar))
            (format t "~A ~A~%" foo bar))

            然后可以這樣調用:
            (foo :bar 'new-bar)
            NIL NEW-BAR

            or
            (foo :bar 'new-bar :foo 'new-foo)
            NEW-FOO NEW-BAR

            or
            (foo :foo 'new-foo)
            NEW-FOO DEFAULT-BAR

            恩,也許可以參考一下,通過名字來指定是哪個參數。  回復  更多評論
              
            # re: 亂序Policy手法 2006-10-22 09:56 Francis Arcanum
            通過名字取參數C++有另外一套做法,可以參見boost.parameter
            這個可以連名字都不需要,哇哈哈哈哈  回復  更多評論
              
            # re: [yc]亂序Policy手法 2007-05-20 07:38 pluskid
            寒~~發現原來我以前看過這篇的。不過現在居然能看懂了,看來自己也是有進步的,哈哈~  回復  更多評論
              
            # re: [yc]亂序Policy手法[未登錄] 2007-08-21 20:17 Jarod
            突然發現有個例子是遺傳算法,莫非朋友也是搞智能的?  回復  更多評論
              
            # re: [yc]亂序Policy手法 2007-08-22 10:27 Francis Arcanum
            @Jarod
            呵呵,不是,只不過有朋友給我介紹過,覺得這個例子很合適就用上了  回復  更多評論
              
            # re: [yc]亂序Policy手法 2009-10-25 12:47 hlysh
            看不懂....唉  回復  更多評論
              
            久久99精品久久久久久野外 | 精品久久久久中文字幕日本| 狠狠色婷婷久久一区二区 | 国内精品九九久久精品| 久久久久久久久久久久中文字幕| 久久91精品国产91久久户| 久久久久免费精品国产| 国产精品99久久久精品无码| 99久久免费国产精精品| 久久久艹| 99久久99久久精品国产片| 久久亚洲国产成人影院| 色综合久久中文色婷婷| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 精品久久久久久久久中文字幕| 日本加勒比久久精品| 国产成人精品免费久久久久| 日本加勒比久久精品| 国产免费久久精品丫丫| 99久久成人国产精品免费| 亚洲精品美女久久久久99| 久久国产成人| 狠狠综合久久综合中文88| 国产午夜福利精品久久2021| 99久久精品国产一区二区| 亚洲国产成人久久综合碰| 久久播电影网| 久久久久九国产精品| 久久99国产一区二区三区| 久久99久久99小草精品免视看| 久久久婷婷五月亚洲97号色| 97精品依人久久久大香线蕉97 | 99久久国产精品免费一区二区| 久久国产成人午夜aⅴ影院| 国产A级毛片久久久精品毛片| 久久国产欧美日韩精品| 97久久天天综合色天天综合色hd| 久久人人爽人人爽人人AV| 久久精品国产亚洲精品2020 | 亚洲精品综合久久| 国产精品99久久久精品无码|