• <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
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(5)

            隨筆分類(38)

            隨筆檔案(31)

            收藏夾(4)

            College

            High School

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 55926
            • 排名 - 407

            最新評(píng)論

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

            閱讀排行榜

            評(píng)論排行榜

                 摘要:   1。符號(hào)查找(對(duì)于函數(shù)此時(shí)只看名字,不看參數(shù))    大致順序是    (1)如果有限定名( XXX:: )那么就直接在XXX里查找    (2)函數(shù)局部名字空間    (3)(如果是成員)類名字空間    (4)遞歸向上至所有基類的...  閱讀全文
            posted @ 2006-12-27 11:04 shifan3 閱讀(2119) | 評(píng)論 (8)編輯 收藏


            發(fā)信人: shifan (學(xué)習(xí)浮云技術(shù)), 板面: C++
            標(biāo)  題: 偽typeof
            發(fā)信站: 飄渺水云間 (Tue Dec 19 16:38:45 2006), 轉(zhuǎn)信
             1 /*
             2 用標(biāo)準(zhǔn)C++實(shí)現(xiàn)typeof是不可能的
             3 這個(gè)是我寫的一個(gè)approached typeof
             4 所有需要被靜態(tài)反射出來(lái)的類型必須先用DECL_TYPE注冊(cè)
             5 模板如果僅僅帶有1個(gè)參數(shù)可以用DECL_TEMPLATE_1注冊(cè)
             6 多個(gè)參數(shù)的模板還不支持。。
             7 主要是沒想好編碼
             8 
             9 總共能注冊(cè)64個(gè)類型
            10 可以通過(guò)MAX_TYPE_NUMBER設(shè)置
            11 
            12 支持的模板嵌套層數(shù)大約為32 / log2(MAX_TYPE_NUMBER)
            13 MAX_TYPE_NUMBER必須為2的整次數(shù)冪
            14 */
            15 namespace my_typeof
            16 {
            17 
            18   const int MAX_TYPE_NUMBER = 64;
            19 
            20   template <int N>
            21   struct dummy
            22   {
            23     int a[N];
            24   };
            25 
            26 
            27   template <int N, typename Arg1>
            28   struct select_by_number_1;
            29 
            30   template <int N>
            31   struct select_by_number
            32   {
            33     typedef typename select_by_number_1<% MAX_TYPE_NUMBER, typename
            34 select_by_number</ MAX_TYPE_NUMBER>::type>::type type;
            35   };
            36 
            37 
            38   template <typename T>
            39   struct number_of
            40   {
            41     static const int v = sizeof(generic_f(*(T*)0)) / sizeof(int);
            42   };
            43 
            44 
            45 #define DECL_TYPE(T, N) \
            46   namespace my_typeof{  \
            47   template<>\
            48   struct select_by_number<N> \
            49   {\
            50     typedef T type;\
            51   };\
            52   dummy <N> generic_f(const T&);}
            53 
            54 
            55 #define DECL_TEMPLATE_1(T, N) \
            56   namespace my_typeof{        \
            57   template<typename Arg1>\
            58   struct select_by_number_1<N, Arg1>\
            59   {\
            60     typedef T<Arg1> type;\
            61   };\
            62   template <typename Arg1>\
            63   dummy<+ number_of<Arg1>::v * MAX_TYPE_NUMBER > generic_f(const T<Arg1>&);}
            64 
            65 
            66 
            67 #define TYPE_OF(x) my_typeof::select_by_number<sizeof(my_typeof::generic_f(x)) /
            68 sizeof (int)>::type
            69 
            70 }
            71 
            72 
            73 //sample
            74 #include <iostream>
            75 #include <vector>
            76 #include <list>
            77 
            78 
            79 DECL_TYPE(int1);
            80 DECL_TEMPLATE_1(std::vector, 2);
            81 DECL_TEMPLATE_1(std::list, 3);
            82 DECL_TYPE(double4)
            83 
            84 using namespace std;
            85 int main(intchar*[])
            86 {
            87   vector<list<vector<list<double> > > > v1;
            88   TYPE_OF(v1) v2;
            89   v1 = v2;
            90   return 0;
            91 }
            92 
            93 


            --
            You well 撒法!You well all 撒法!

            ※ 內(nèi)容修改:·shifan 于 Dec 21 14:21:57 修改本文內(nèi)容·[FROM: shifan]
            ※ 來(lái)源:·飄渺水云間 freecity.cn·[FROM: shifan]
            posted @ 2006-12-21 14:29 shifan3 閱讀(2646) | 評(píng)論 (8)編輯 收藏

            真令人傷感,每過(guò)幾年就是離別時(shí)。

            我站在窗前,無(wú)奈的看著朋友們?yōu)榱斯ぷ鞅甲撸?br />而不能幫上哪怕一點(diǎn)忙。
            就像十年前,就像六年前,就像三年前
            就像每一次與人擦肩而過(guò)卻故意目不斜視。
            但這一次也許好一點(diǎn),畢竟我們以后可能還能時(shí)常相聚,
            而不像現(xiàn)在只能看著從前的好友的博客獨(dú)自傷感。
            那種陌生,令人心碎。

            ?

            posted @ 2006-11-01 00:31 shifan3 閱讀(595) | 評(píng)論 (4)編輯 收藏

            boost的integer/integer_mask.hpp僅僅做了單個(gè)位的bit mask
            要多個(gè)位必須寫很多遍high_bit_mask_t
            使用low_bits_mask_t也不能完全解決問(wèn)題
            所以自己用Typelist的那種寫法寫了一個(gè)

            用法舉例
            bit_mask<INT_LIST_2(2, 3)>::value返回一個(gè)值,該值的第2、3位被置為1
            其余位為0

             

              1 
              2 namespace multi_bit_mask
              3 {
              4     namespace details
              5     {
              6 
              7         template <typename T>
              8         struct get_size
              9         {
             10             enum {size = sizeof(T)}; 
             11         };
             12 
             13         template <int Bit>
             14         struct bit_storage
             15         {
             16             typedef typename bit_storage<Bit - 1>::storage_type storage_type;
             17         };
             18 
             19         //---------platform dependency-----------------------
             20 
             21         typedef unsigned int smallest_storage_type;
             22         typedef unsigned long long largest_storage_type;
             23 
             24         
             25 
             26         template <>
             27         struct bit_storage<0>
             28         {
             29             typedef smallest_storage_type storage_type;
             30         };
             31 
             32         template <>
             33         struct bit_storage<get_size<smallest_storage_type>::size * 8>
             34         {
             35             typedef largest_storage_type storage_type;
             36         };
             37 
             38         //disable the 65th bit
             39         template <>
             40         struct bit_storage<get_size<largest_storage_type>::size * 8>
             41         {
             42             typedef void storage_type;
             43         };
             44         
             45         //---------end of platform dependency----------------
             46 
             47 
             48         template <unsigned int N, typename Next>
             49         struct int_list
             50         {
             51             typedef typename bit_storage<N>::storage_type storage_type;
             52             static const storage_type value = N;
             53             typedef Next next;
             54         };
             55 
             56         struct null_type{};
             57 
             58         template<typename T1, typename T2, bool is_first>
             59         struct selector
             60         {
             61             typedef T1 type;
             62         };
             63 
             64         template<typename T1, typename T2>
             65         struct compare_type
             66         {
             67             const static bool is_larger = sizeof(T1) > sizeof(T2);
             68             typedef typename selector<T1, T2, is_larger>::type large_type;
             69             typedef typename selector<T1, T2, !is_larger>::type small_type;
             70         };
             71 
             72 
             73 
             74         template<typename T1, typename T2>
             75         struct selector<T1, T2, false>
             76         {
             77             typedef T2 type;
             78         };
             79 
             80         template <typename List>
             81         class find_largest_storage
             82         {
             83             typedef typename find_largest_storage<typename List::next>::storage_type T1;
             84             typedef typename bit_storage<List::value>::storage_type T2;
             85         public:
             86             typedef typename compare_type<T1, T2>::large_type storage_type;
             87         };
             88 
             89         template <>
             90         class find_largest_storage<null_type>
             91         {
             92         public:
             93             typedef smallest_storage_type storage_type;
             94         };    
             95 
             96         
             97     }
             98 
             99 
            100         
            101 
            102 
            103     template <int N>
            104     struct single_bit_mask
            105     {
            106         typedef typename details::bit_storage<N>::storage_type storage_type;
            107         static const storage_type value 
            108             = static_cast<storage_type>(single_bit_mask<- 1>::value) * 2;
            109     };
            110 
            111     template <>
            112     struct single_bit_mask<0>
            113     {
            114         typedef details::bit_storage<0>::storage_type storage_type;
            115         static const storage_type value = 1;
            116     };
            117 
            118     
            119     typedef details::null_type null_type;
            120 
            121     template <int N, typename Next>
            122     struct int_list_t : public details::int_list<N, Next> {};
            123 
            124     template <typename List>
            125     struct bit_mask
            126     {
            127     public:
            128 
            129         typedef typename details::find_largest_storage<List>::storage_type storage_type;
            130     
            131         static const storage_type value 
            132             = static_cast<storage_type>(single_bit_mask<List::value>::value) 
            133             | static_cast<storage_type>(bit_mask<typename List::next>::value);
            134     };
            135 
            136     template <>
            137     struct bit_mask<null_type>
            138     {
            139         typedef details::bit_storage<0>::storage_type storage_type;
            140         static const storage_type value = 0;
            141     };
            142 
            143     
            144 
            145     
            146 
            147     #define INT_LIST_1(n1) multi_bit_mask::int_list_t<n1, multi_bit_mask::null_type>
            148     #define INT_LIST_2(n1, n2) multi_bit_mask::int_list_t<n1, INT_LIST_1(n2) > 
            149     #define INT_LIST_3(n1, n2, n3) multi_bit_mask::int_list_t<n1, INT_LIST_2(n2, n3) > 
            150     #define INT_LIST_4(n1, n2, n3, n4) multi_bit_mask::int_list_t<n1, INT_LIST_3(n2, n3, n4) > 
            151     #define INT_LIST_5(n1, n2, n3, n4, n5) multi_bit_mask::int_list_t<n1, INT_LIST_4(n2, n3, n4, n5) > 
            152     #define INT_LIST_6(n1, n2, n3, n4, n5, n6) multi_bit_mask::int_list_t<n1, INT_LIST_5(n2, n3, n4, n5, n6) > 
            153     #define INT_LIST_7(n1, n2, n3, n4, n5, n6, n7) multi_bit_mask::int_list_t<n1, INT_LIST_6(n2, n3, n4, n5, n6, n7) > 
            154     #define INT_LIST_8(n1, n2, n3, n4, n5, n6, n7, n8) multi_bit_mask::int_list_t<n1, INT_LIST_7(n2, n3, n4, n5, n6, n7, n8) > 
            155     
            156 }
            157 
            158 
            159 


            sample

            #include  < iostream >
            #include 
            " multi_bit_mask.h "
            using   namespace  std;
            int  main()
            {
                cout 
            <<  multi_bit_mask::bit_mask < INT_LIST_1( 1 ) > ::value  <<  endl;
                cout 
            <<  multi_bit_mask::bit_mask < INT_LIST_5( 0 1 2 3 4 ) > ::value  <<  endl;
                cout 
            <<  multi_bit_mask::bit_mask < INT_LIST_7( 0 1 2 3 4 4 2 ) > ::value  <<  endl;
                
            posted @ 2006-10-26 23:37 shifan3 閱讀(1453) | 評(píng)論 (2)編輯 收藏

                近日在學(xué)校bbs上與人討論C++的typeid關(guān)鍵字的實(shí)現(xiàn)問(wèn)題,有人提到type_info的地址是存放在虛表的第一個(gè)位置上,頗覺得不妥,于是我在vc2003下實(shí)驗(yàn)了一番

                在vc下,使用typeid的時(shí)候,如果typeid施加給的類型是沒有vptr的class或者根本不是class
            那么匯編是
            mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
            也就是編譯器生成一個(gè)簡(jiǎn)單的type_info對(duì)象的表,并且在編譯期靜態(tài)決定下標(biāo),做一個(gè)簡(jiǎn)單查表操作。

            如果typeid的操作對(duì)象是具有vptr的class,但是并不是一個(gè)引用或者指針的解引用形式,例如

            A a;
            typeid(a);


            那么仍然僅僅會(huì)做查表操作


            如果typeid的操作對(duì)象是具有vptr的class,并且是引用或者指針的解引用形式,例如

            * =   new  A;
            A
            &  r  =   * p;
            typeid(
            * p);
            typeid(r);


            那么就會(huì)調(diào)用一個(gè)叫___RTtypeid的函數(shù),并通過(guò)某種方法來(lái)獲取type_info對(duì)象
            下面是___RTtypeid的反匯編,這里只列出關(guān)鍵的幾條指令

            0041213E  mov         ecx,dword ptr [inptr]    ;inptr是對(duì)象的地址
            00412141   mov         edx,dword ptr [ecx] 
            00412143   mov         eax,dword ptr [edx - 4
            0041215F  mov         ecx,dword ptr [eax
            + 0Ch] 
            00412162   mov         dword ptr [ebp - 48h],ecx 
            0041216C  mov         eax,dword ptr [ebp
            - 48h] 


            基本上等價(jià)于C語(yǔ)言的

            int  a1  =  ( int )p;  // p是對(duì)象的地址
            int  a2  =   * ( int * )a1  -   4 ;
            int  a3  =   * ( int * )a2  +   12 ;
            int  a4  =   * ( int * )a3;

             

            那么從這段代碼可以看出vc下type_info對(duì)象的存放位置[如下圖]



            也就虛表下標(biāo)為-1的位置上存放了一個(gè)指向一個(gè)未知的表的指針(暫且將此表命名為runtime_info_table)
            runtime_info_table的第4格上存放了type_info對(duì)象的地址
            至于runtime_info_table里前3格上存放的是什么, 還需要再研究研究
            一般來(lái)說(shuō)它們?nèi)?, 但是對(duì)于多重虛繼承的類, 第二格上會(huì)是4, 可能和指針的偏移量有關(guān).

            posted @ 2006-10-26 10:46 shifan3 閱讀(3350) | 評(píng)論 (5)編輯 收藏
            Xpressive是一個(gè)C++的正則表達(dá)式庫(kù),目前是Boost的候選庫(kù)。
            Xpressive和Boost.Regex的區(qū)別很大。首先,Xpressive是一個(gè)純頭文件的庫(kù),也是說(shuō),在使用之前不需要預(yù)先編譯。其次,Xpressive支持類似于Spirit的靜態(tài)語(yǔ)義定義。

            我們先來(lái)看一個(gè)例子:

             

            #include <iostream>
            #include 
            <boost/xpressive/xpressive.hpp>

            using namespace boost::xpressive;

            int main()
            {
                std::
            string hello( "hello world!" );

                sregex rex 
            = sregex::compile( "(\\w+) (\\w+)!" );
                smatch what;

                
            if( regex_match( hello, what, rex ) )
                {
                    std::cout 
            << what[0<< '\n'// whole match
                    std::cout << what[1<< '\n'// first capture
                    std::cout << what[2<< '\n'// second capture
                }

                
            return 0;
            }

            這是使用Xpressive動(dòng)態(tài)語(yǔ)義定義的例子,其中sregex::compile函數(shù)編譯一個(gè)表示正則文法的串,并返回一個(gè)正則對(duì)象sregex
            使用regex_match來(lái)使用這個(gè)正則對(duì)象匹配一個(gè)串。結(jié)果儲(chǔ)存在what內(nèi)
            其中what[0]返回整個(gè)串,what[1]~what[n]返回文法中用于標(biāo)記的部分(用小括號(hào)括起來(lái)的部分)
            最后將輸出
                 hello world!
                 hello
                 world

            如果想在一個(gè)串中查找符合該文法的子串,可以使用regex_search,用法和regex_match一樣,此外還可以用regex_replace來(lái)進(jìn)行替換。

             


            靜態(tài)文法:
            Xpressive除了可以用compile來(lái)分析一個(gè)文法串之外,還可以用類似于Spirit的方式來(lái)靜態(tài)的指定文法:

            sregex re = '$' >> +_d >> '.' >> _d >> _d;

            這將定義一個(gè)表示金額的串,其中_d表示一個(gè)數(shù)字,相當(dāng)于串 $\d+.\d\d
            這樣定義文法將比之前的動(dòng)態(tài)定義更加高效,并且還有一個(gè)附加的好處:
            分級(jí)定義:

            sregex re = '$' >> +_d >> '.' >> _d >> _d;
            sregex s 
            = '(' >> re >> ')';

            這樣s表示為用括號(hào)括起來(lái)的re
            通過(guò)分級(jí)定義,文法能被表示的更加清楚。
            更加棒的是,分級(jí)定義還可以向后引用,因此能夠分析EBNF

            sregex group, factor, term, expression;
            group       
            = '(' >> by_ref(expression) >> ')';
            factor      
            = +_d | group;
            term        
            = factor >> *(('*' >> factor) | ('/' >> factor));
            expression  
            = term >> *(('+' >> term) | ('-' >> term));

            expression定義了一個(gè)四則表達(dá)式,注意其中g(shù)roup的定義。
            這里必須使用by_ref是因?yàn)閄pressive默認(rèn)是值拷貝,如果這里使用默認(rèn)的方式,那么會(huì)造成一個(gè)無(wú)限循環(huán)。


            Xpressive可以在這里下載
            http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&direction=0&order=&directory=Strings%20-%20Text%20Processing&PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535
            內(nèi)有詳細(xì)的文檔

            posted @ 2006-07-27 16:27 shifan3 閱讀(3116) | 評(píng)論 (4)編輯 收藏

            看了546@C++@Freecity之后,發(fā)覺非常有意思,由此產(chǎn)生一些想法

            很多時(shí)候?qū)懸粋€(gè)類的時(shí)候,需要多個(gè)模版參數(shù),例如一個(gè)遺傳算法的算法類,需要一個(gè)模版參數(shù)來(lái)指定交配方式,另一個(gè)模版參數(shù)來(lái)指定子代選擇的方式,還要一個(gè)參數(shù)來(lái)指定變異的方式。那么一般來(lái)說(shuō),這個(gè)類會(huì)寫成:

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

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

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

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

            如何在一個(gè)TypeList中查找一個(gè)類型的子類?
            首先要有一個(gè)IsDerivedFrom<Base, T>
            這個(gè)比較簡(jiǎn)單
            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;
            };

            當(dāng)然還要對(duì)一些特殊情況進(jìn)行特化,例如NullType
            template <class Base>
            struct FindChild<NullType, Base>
            {
                    typedef NullType Type;
            };
            這里使用NullType來(lái)表明沒找到

            實(shí)際操作:
            首先需要給3個(gè)Policy3個(gè)基類,分別叫
            class AvgCrossPolicyBase{};
            class SelectPolicyBase{};
            class VariationPolicyBase{};
            內(nèi)容為空就行了,這樣也沒有虛函數(shù)調(diào)用的開銷


            然后聲明一個(gè)類來(lái)表示默認(rèn)情況:
            class DefaultPolicy{};

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

            下面要寫一些選擇器,用于把合適的類型選擇出來(lái),如果沒找到,則要使用默認(rèn)的類型
            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;
            };

            好啦,現(xiàn)在整個(gè)類的聲明可以寫為

            template<class T
                    , class CrossPolicy_ = DefaultPolicy
                    , class SelectPolicy_ = DefaultPolicy
                    , class VariationPolicy_ = DefaultPolicy     //其后的參數(shù)用戶不可指定
                    , 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個(gè)參數(shù)(List,CrossPolicy,SelectPolicy和VariationPolicy)是不由用戶指定的,僅僅是為了起一個(gè)別名
            第一個(gè)參數(shù)T必須指定,然后2,3,4這3個(gè)參數(shù)就可以任意的改變順序了
            例如,可以寫Gene<T, DefaultSelectPolicy, AvgCrossPolicy>而不會(huì)有任何問(wèn)題
            如果不想要最后面幾個(gè)參數(shù)的話也行,但是代碼就要稍微長(zhǎng)一點(diǎn)
            而且最好在類里面進(jìn)行3個(gè)typedef
            typedef typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type CrossPolicy;
            等,以便在實(shí)現(xiàn)的時(shí)候使用

            posted @ 2006-07-24 01:06 shifan3 閱讀(1012) | 評(píng)論 (9)編輯 收藏
                 摘要: 發(fā)信人: shifan (家沒有豚豚 T.T), 板面: C++標(biāo)  題: 如何實(shí)現(xiàn)Lambda[第二部分]發(fā)信站: 飄渺水云間 (Thu Jun  8 23:30:20 2006), 轉(zhuǎn)信 章節(jié):八:第一部分的小結(jié)九:簡(jiǎn)化,如何減少Lambda代碼的冗余和依賴性十:bind的實(shí)現(xiàn)十一:實(shí)現(xiàn)phoenix 八.    中期總結(jié)目前的結(jié)果是這樣的...  閱讀全文
            posted @ 2006-07-15 15:32 shifan3 閱讀(992) | 評(píng)論 (0)編輯 收藏
                 摘要: 一. 什么是Lambda所謂Lambda,簡(jiǎn)單的說(shuō)就是快速的小函數(shù)生成。在C++中,STL的很多算法都要求使用者提供一個(gè)函數(shù)對(duì)象。例如for_each函數(shù),會(huì)要求用戶提供一個(gè)表明“行為”的函數(shù)對(duì)象。以vector<bool>為例,如果想使用for_each對(duì)其中的各元素全部賦值為true,一般需要這么一個(gè)函數(shù)對(duì)象,     c...  閱讀全文
            posted @ 2006-06-09 13:23 shifan3 閱讀(2993) | 評(píng)論 (7)編輯 收藏

                最近為了解析SQL語(yǔ)法,懷著試一試的心態(tài)去翻了翻boost的spirit庫(kù),因?yàn)樵搸?kù)的文檔的簡(jiǎn)介里寫著LL parser framework  represents parsers directly as EBNF grammars in inlined C++。看著framework這個(gè)詞自然覺得這個(gè)庫(kù)很牛B,試用了一下果然如此。
                所謂EBNF即擴(kuò)展巴克斯范式,是一種描述Context-Free Language的文法。在目前常見的非自然語(yǔ)言中,大部分都可以用EBNF表示。例如:
                  group  ::='('exp
            ')'
                  factor ::=integer|
            group
                  term   ::=factor(('*'factor)|('/'factor
            ))*
                  exp    ::=term(('+'term)|('-'term
            ))*
            這是一個(gè)整數(shù)表達(dá)式的EBNF。該段描述用spirit在C++中的實(shí)現(xiàn)則是:
               

               rule<> group, factor, term, exp;
               group  
            = '(' >> exp >> ')';
               factor 
            = int_p | group;
               term   
            = factor >> *(('*' >> factor) | ('/' >> factor));
               exp    
            = term >> *(('+' >> term) | ('-' >> term));

            這里使用=代替::=, 用>>代替空格連接。并且由于C++語(yǔ)法所限,EBNF中后置的*在spirit中改為前置。
            等式左邊的單詞被稱為一個(gè)rule,等式右邊為rule的定義。我們可以看出一個(gè)group是一個(gè)exp加上一對(duì)括號(hào),一個(gè)factor是一個(gè)整數(shù)或者一個(gè)group,一個(gè)term是一個(gè)或多個(gè)factor用*/連接,一個(gè)exp是一個(gè)或多個(gè)term用+-連接。處于最頂端的exp可以據(jù)此識(shí)別出以下表達(dá)式
               

               12345
               
            -12345
               
            +12345
               
            1 + 2
               
            1 * 2
               
            1/2 + 3/4
               
            1 + 2 + 3 + 4
               
            1 * 2 * 3 * 4
               (
            1 + 2* (3 + 4)
               (
            -1 + 2* (3 + -4)
               
            1 + ((6 * 200- 20/ 6
               (
            1 + (2 + (3 + (4 + 5))))

                得到一個(gè)rule之后,我們就可以用 parse函數(shù)對(duì)一個(gè)串進(jìn)行識(shí)別了。例如
                     

                     parse( " (1 + (2 + (3 + (4 + 5)))) " , exp);


            該函數(shù)返回一個(gè)結(jié)構(gòu)parse_info,可以通過(guò)訪問(wèn)其中的full成員來(lái)判斷是否成功識(shí)別,也可以訪問(wèn)stop成員來(lái)獲知失敗的位置。這里要特別提一點(diǎn),關(guān)于各個(gè)符號(hào)之間的空格,spirit的文檔的正文說(shuō)的是給parse再傳一個(gè)參數(shù)space_p,通知parse跳過(guò)所有的空格,然而在FAQ中又提到,如果使用以上方法定義rule,第三個(gè)參數(shù)傳space_p會(huì)失敗。原因是使用rule默認(rèn)定義的規(guī)則被稱為character level parsing,即字符級(jí)別解析,而parse的第3個(gè)參數(shù)僅適用于phrase level parsing,即語(yǔ)法級(jí)別解析。要使用第3個(gè)參數(shù)可以有幾種方法。
                  1。在parse的第二個(gè)參數(shù)直接傳入一個(gè)EBNF表達(dá)式,不創(chuàng)建rule對(duì)象。
                     

                        parse( " hello world " * anychar_p, space_p);  


                  2。以rule<phrase_scanner_t>創(chuàng)建rule。
                     

                        rule < phrase_scanner_t >  exp; 

            注意雖然可以用這兩個(gè)辦法屏蔽空格,但是這樣可能完全改變EBNF文法的語(yǔ)義,尤其是在語(yǔ)言本身需要識(shí)別空格的時(shí)候。對(duì)于這種情況,可以不使用第三個(gè)參數(shù),并在需要出現(xiàn)空格的地方加上space_p,或者+space_p及*space_p,其中+和*分別表示后面的符號(hào)連續(xù)出現(xiàn)一次以上和0次以上。例如一個(gè)以空格分隔的整數(shù)列表可以寫成int_p >> *(+space_p >> int_p)
               如上使用parse可以識(shí)別一個(gè)串,但并不能做更多的操作,例如將語(yǔ)法里的各個(gè)成分提取出來(lái)。對(duì)于這樣的需求,可以通過(guò)actor實(shí)現(xiàn)。下面是使用actor的一個(gè)簡(jiǎn)單例子
               

               bool
               parse_numbers(
            char const* str, vector<double>& v)
               
            {
                  
            return parse(str,

               
            //  Begin grammar
                  (
                     real_p[push_back_a(v)] 
            >> *(',' >> real_p[push_back_a(v)])
                  )
                  ,
                  
            //  End grammar
                  space_p).full;
               }

            注意到real_p后面的[],中括號(hào)里面是一個(gè)仿函數(shù)(函數(shù)指針或者函數(shù)對(duì)象),該仿函數(shù)具有如下調(diào)用型別
               

               void operator()(IterT first, IterT last) const;
               
            void operator()(NumT val) const;
               
            void operator()(CharT ch) const;


            一旦spase發(fā)現(xiàn)了匹配real_p的子串,就會(huì)調(diào)用該functor。不同的rule可能會(huì)對(duì)應(yīng)不同的調(diào)用型別。
            第一個(gè)型別針對(duì)一般規(guī)則,first和last為兩個(gè)指向字符的迭代器(一般為char*),匹配的子串為[first, last)
            第二個(gè)型別針對(duì)數(shù)字型規(guī)則,如real_p和int_p, 參數(shù)val是一個(gè)數(shù)字類型。
            第三個(gè)性別針對(duì)單字符型規(guī)則,如space_p, 參數(shù)ch是一個(gè)字符類型。
            real_p[push_back_a(v)]中的push_back_a是一個(gè)spirit已經(jīng)定義好的functor,它會(huì)將匹配好的內(nèi)容依照匹配到的時(shí)間順序調(diào)用v的push_back函數(shù)加入到v中。

               到此spirit的常用功能就都介紹完了。要詳細(xì)深入了解可以參考spirit的文檔。

            最后在題一個(gè)注意要點(diǎn)。spirit的各種EBNF連接都是指針連接,因此才能在expression被賦值前就在group的定義里面使用。所以在使用EBNF的時(shí)候一定要小心不要將局部變量的rule提供給全局或者類成員變量使用,例如:
               

               class A
               
            {
                  rule
            <> s;
                  A()
                  
            {
                     rule
            <> r = int_p | hex_p;

                     s 
            = r >> *(+space_p >> r); //error, r destructed after return 
                  }

               }
            ;

            如果真想使用局部作用域,可以在局部的rule前面加上static.

            posted @ 2005-12-18 12:02 shifan3 閱讀(7122) | 評(píng)論 (5)編輯 收藏
            僅列出標(biāo)題
            共3頁(yè): 1 2 3 
            久久综合丁香激情久久| 品成人欧美大片久久国产欧美...| 亚洲人成伊人成综合网久久久| 久久人人爽人人爽人人AV东京热 | 久久亚洲国产成人影院网站 | 色偷偷91久久综合噜噜噜噜| 亚洲精品国精品久久99热一| 久久精品亚洲福利| 国产精品久久久久久一区二区三区| 久久亚洲高清综合| 波多野结衣久久一区二区| 久久亚洲国产午夜精品理论片| 66精品综合久久久久久久| 99久久精品国内| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 亚洲国产小视频精品久久久三级| 久久99精品国产99久久| 国产亚洲精品美女久久久| 亚洲AV无一区二区三区久久 | 亚洲国产精品成人久久蜜臀 | 久久精品亚洲AV久久久无码| 人妻无码精品久久亚瑟影视| 人妻无码精品久久亚瑟影视| 久久99国产精品尤物| 久久精品国产精品亚洲人人| 久久精品国产99国产精品亚洲| 国产精品一区二区久久国产| 99久久亚洲综合精品成人| 99久久免费国产精品| 亚洲乱码日产精品a级毛片久久 | 久久精品人人做人人妻人人玩| 久久综合一区二区无码| 亚洲色欲久久久综合网| 91精品婷婷国产综合久久| 国产精品99久久久久久宅男小说| 国产精品久久影院| 久久大香萑太香蕉av| 久久r热这里有精品视频| 久久精品国产99国产精品导航| 久久无码av三级| 无码人妻精品一区二区三区久久久 |