• <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>
            Cpper
            C/C++高級工程師 Android高級軟件工程師 IT集成工程師 音頻工程師 熟悉c,c++,java,c#,py,js,asp等多種語言 程序猿

            以前大致看過模板元編程但是并沒有深入進去
            現在就拿比較小的Loki庫研究了
            本文主要涉及的是其頭文件TypeMapIP.h
            1.根據給定常量生成對等枚舉變量

            ////////////////////////////////////////////////////////////////////////////////
            // class template Int2Type
            // Converts each integral constant into a unique type
            // Invocation: Int2Type<v> where v is a compile-time constant integral
            // Defines 'value', an enum that evaluates to v
            ////////////////////////////////////////////////////////////////////////////////

                template 
            <int v>
                
            struct Int2Type
                {
                    
            enum { value = v };
                };
            正如所說:v是一個編譯期常量整數
            2.類型重定義
            ////////////////////////////////////////////////////////////////////////////////
            // class template Type2Type
            // Converts each type into a unique, insipid type
            // Invocation Type2Type<T> where T is a type
            // Defines the type OriginalType which maps back to T
            ////////////////////////////////////////////////////////////////////////////////

                template 
            <typename T>
                
            struct Type2Type
                {
                    typedef T OriginalType;
                };
            舉例子為:
            Type2Type<vector<int> >::OriginalType v;
            當前蓋莫引擎就是這樣使用鏈表的O(∩_∩)O~如下:
                #include <loki/flex/flex_string.h>
                typedef flex_string
            <char> engine_string;
                #include 
            <loki/yasli/yasli_vector.h>     
                template
            <class T>      
                
            struct vector_typedef
                {
                    typedef yasli::vector
            <T,std::allocator<T> > type;
                };   
                template
            <class T>      
                
            struct list_typedef
                {
                    typedef yasli::vector
            <T,std::allocator<T> > type;       
                };        
            #endif 
            基本上是模板重定義
            3.條件類型重定義
            ////////////////////////////////////////////////////////////////////////////////
            // class template Select
            // Selects one of two types based upon a boolean constant
            // Invocation: Select<flag, T, U>::Result
            // where:
            // flag is a compile-time boolean constant
            // T and U are types
            // Result evaluates to T if flag is true, and to U otherwise.
            ////////////////////////////////////////////////////////////////////////////////

                template 
            <bool flag, typename T, typename U>
                
            struct Select
                {
                    typedef T Result;
                };
                template 
            <typename T, typename U>
                
            struct Select<false, T, U>
                {
                    typedef U Result;
                };
            舉例為:
            Select<true,int,char>::Result r;
            則r為int 類型
            Seclet<false,int,char>::Result r
            r為char類型
            這樣的例子基本上在所有模板元編程書上都可以看到
            當然還有很多代碼,比如DyObjLib庫
            4.檢測對象是否為同一類型
                template <typename T, typename U>
                
            struct IsSameType
                {
                    
            enum { value = false };
                };
                
                template 
            <typename T>
                
            struct IsSameType<T,T>
                {
                    
            enum { value = true };
                };
            記得以前我看到這個的時候感覺實現的太巧妙了
            5.Conversion模板
            ////////////////////////////////////////////////////////////////////////////////
            // class template Conversion
            // Figures out the conversion relationships between two types
            // Invocations (T and U are types):
            // a) Conversion<T, U>::exists
            // returns (at compile time) true if there is an implicit conversion from T
            // to U (example: Derived to Base)
            // b) Conversion<T, U>::exists2Way
            // returns (at compile time) true if there are both conversions from T
            // to U and from U to T (example: int to char and back)
            // c) Conversion<T, U>::sameType
            // returns (at compile time) true if T and U represent the same type
            //
            // Caveat: might not work if T and U are in a private inheritance hierarchy.
            ////////////////////////////////////////////////////////////////////////////////
            Conversion模板指出了給定2個類型之間的轉換關系
            具體源碼為:
                template <class T, class U>
                
            struct Conversion
                {
                    typedef Private::ConversionHelper
            <T, U> H;
            #ifndef __MWERKS__
                    
            enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
            #else
                    
            enum { exists = false };
            #endif
                    
            enum { exists2Way = exists && Conversion<U, T>::exists };
                    
            enum { sameType = false };
                };
            _MWERKS是什么宏定義
            先不管它
            再看其特化形式
                template <class T>
                
            struct Conversion<T, T>    
                {
                    
            enum { exists = 1, exists2Way = 1, sameType = 1 };
                };
                
                template 
            <class T>
                
            struct Conversion<void, T>    
                {
                    
            enum { exists = 0, exists2Way = 0, sameType = 0 };
                };
                
                template 
            <class T>
                
            struct Conversion<T, void>    
                {
                    
            enum { exists = 0, exists2Way = 0, sameType = 0 };
                };
                
                template 
            <>
                
            struct Conversion<voidvoid>    
                {
                
            public:
                    
            enum { exists = 1, exists2Way = 1, sameType = 1 };
                };

            這里給定了4種特化形式
            3個涉及void類型
            1個涉及類型相同
            可以看出:
            如果2個對象類型相同則枚舉變量sameType必定為真
            關于枚舉變量exists
            如果其為真則說明T類型可以轉化為U類型(比如子類到父類)
            關于變量exists2Way表達的是U,T類型是否可以雙向轉化(比如int,和long類型)
            6.繼承關系的鑒別
            ////////////////////////////////////////////////////////////////////////////////
            // class template SuperSubclass
            // Invocation: SuperSubclass<B, D>::value where B and D are types. 
            // Returns true if B is a public base of D, or if B and D are aliases of the 
            // same type.
            //
            // Caveat: might not work if T and U are in a private inheritance hierarchy.
            ////////////////////////////////////////////////////////////////////////////////
            如果B類型是D類型的公共父類則結果為真
            否則為假
            代碼為:
            template <class T, class U>
            struct SuperSubclass
            {
                
            enum { value = (::Loki::Conversion<const volatile U*const volatile T*>::exists &&
                              
            !::Loki::Conversion<const volatile T*const volatile void*>::sameType) };
                  
                
            // Dummy enum to make sure that both classes are fully defined.
                enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
            };

            template 
            <>
            struct SuperSubclass<voidvoid> 
            {
                
            enum { value = false };
            };

            template 
            <class U>
            struct SuperSubclass<void, U> 
            {
                
            enum { value = (::Loki::Conversion<const volatile U*const volatile void*>::exists &&
                              
            !::Loki::Conversion<const volatile void*const volatile void*>::sameType) };
                  
                
            // Dummy enum to make sure that both classes are fully defined.
                enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
            };

            template 
            <class T>
            struct SuperSubclass<T, void> 
            {
                
            enum { value = (::Loki::Conversion<const volatile void*const volatile T*>::exists &&
                              
            !::Loki::Conversion<const volatile T*const volatile void*>::sameType) };
                  
                
            // Dummy enum to make sure that both classes are fully defined.
                enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
            };
            其幾種特化形式都與void類型有關
            再看其value描述:
                enum { value = (::Loki::Conversion<const volatile void*const volatile T*>::exists &&
                              
            !::Loki::Conversion<const volatile T*const volatile void*>::sameType) };
            當void*可以轉化為T*同時T*類型不為void*時則value為真
            enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
            該枚舉變量時防止類型變量存在不完全類型
            可以看出在模板元編程中可以使用enum變量來處理和預報錯誤
            給定一個例子
            #include <iostream>
            #include 
            <string>
            #include 
            <Loki/TypeManIP.h>
            #include 
            <typeinfo>

            class A; 
             
            int main()
            {
                std::cout
            <<Loki::SuperSubclass<void,A>::dontUseWithIncompleteTypes<<std::endl; 
                system(
            "PAUSE");
                
            return EXIT_SUCCESS;
            }
            編譯器會報出一個194 E:\c++header\Loki\TypeManIP.h invalid application of `sizeof' to incomplete type `A'  錯誤
            7.對象嚴格繼承關系的鑒別
            ////////////////////////////////////////////////////////////////////////////////
            // class template SuperSubclassStrict
            // Invocation: SuperSubclassStrict<B, D>::value where B and D are types. 
            // Returns true if B is a public base of D.
            //
            // Caveat: might not work if T and U are in a private inheritance hierarchy.
            ////////////////////////////////////////////////////////////////////////////////

            template
            <class T,class U>
            struct SuperSubclassStrict
            {
                
            enum { value = (::Loki::Conversion<const volatile U*const volatile T*>::exists &&
                             
            !::Loki::Conversion<const volatile T*const volatile void*>::sameType &&
                             
            !::Loki::Conversion<const volatile T*const volatile U*>::sameType) };
                
                
            // Dummy enum to make sure that both classes are fully defined.
                enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
            };

            template
            <>
            struct SuperSubclassStrict<voidvoid> 
            {
                
            enum { value = false };
            };

            template
            <class U>
            struct SuperSubclassStrict<void, U> 
            {
                
            enum { value = (::Loki::Conversion<const volatile U*const volatile void*>::exists &&
                             
            !::Loki::Conversion<const volatile void*const volatile void*>::sameType &&
                             
            !::Loki::Conversion<const volatile void*const volatile U*>::sameType) };
                
                
            // Dummy enum to make sure that both classes are fully defined.
                enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
            };

            template
            <class T>
            struct SuperSubclassStrict<T, void> 
            {
                
            enum { value = (::Loki::Conversion<const volatile void*const volatile T*>::exists &&
                             
            !::Loki::Conversion<const volatile T*const volatile void*>::sameType &&
                             
            !::Loki::Conversion<const volatile T*const volatile void*>::sameType) };
                
                
            // Dummy enum to make sure that both classes are fully defined.
                enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
            };
            以上是代碼段
            當然以上2種類型檢測都不能處理私有繼承的關系
            下面是簡單的測試例子:

            #include <iostream>
            #include 
            <string>
            #include 
            <Loki/TypeManIP.h>
            #include 
            <typeinfo>

            class B
            {}; 

            class D : public B
            {
            };
             
            int main()
            {
                std::cout
            <<LOKI_SUPERSUBCLASS(B,D)<<std::endl; 
                std::cout
            <<LOKI_SUPERSUBCLASS(D,B)<<std::endl; 
                std::cout
            <<LOKI_SUPERSUBCLASS(B,int)<<std::endl; 
                std::cout
            <<LOKI_SUPERSUBCLASS(long,D)<<std::endl; 
                system(
            "PAUSE");
                
            return EXIT_SUCCESS;
            }
            TypemanIp看完了
            8.最后我給出我看到的另外一種檢測對象是否含有Vtable的檢測手法:
            template<class T>
            struct IsVObjImpl {
                
            struct IA : public T {
                    
            int m;
                };
                
            struct IB : public T {
                    
            virtual void F( );
                    
            int m;
                };
                
            enum { v = (sizeof(IA)==sizeof(IB)) };
            };
            首先定義2個類對象他們都繼承于給定類型
            然后一個還有Vtable
            一個不含有Vtable
            之后偵測其size是否相同
            可以看出vtable是不占有子類大小的
            測試例子如下:
            #include <iostream>
             
            template
            <class T>
            struct IsVObjImpl 
            {
                
            struct IA : public T {
                    
            int m;
                };
                
            struct IB : public T {
                    
            virtual void F( );
                    
            int m;
                };
                
            enum { v = (sizeof(IA)==sizeof(IB)) };
            };
             
            class A
            {
               
            virtual void v(){}      
            }; 

            class B
            {
               
            void v(){}      
            }; 

             
            int main()
            {
                std::cout
            <<IsVObjImpl<A>::v<<std::endl;
                std::cout
            <<IsVObjImpl<B>::v<<std::endl;
                system(
            "PAUSE");
                
            return EXIT_SUCCESS;
            }

            9.一些其他的對象類型測試手法:
            // Check if type is const
            template <class T>
            struct DoIsConst {
                
            enum { v=0 };
            };

            template 
            <class T>
            struct DoIsConst<const T> {
                
            enum { v=1 };
            };

            template 
            <class T>  // Should this be needed?
            struct DoIsConst<const T&> {
                
            enum { v=1 };
            };

            template 
            <class T>  // Should this be needed?
            struct DoIsConst<const T*> {
                
            enum { v=1 };
            };


            /////////////////////////////////////////
            // Check if type is a ref or not
            template <class T>
            struct DoIsRef {
                
            enum { v=0 };
            };

            template 
            <class T>
            struct DoIsRef<T&> {
                
            enum { v=1 };
            };


            /////////////////////////////////////////
            // Check if type is a pointer or not
            template <class T>
            struct DoIsPointer {
                
            enum { v=0 };
            };

            template 
            <class T>
            struct DoIsPointer<T*> {
                
            enum { v=1 };
            };
            這些東西都源于DyObj
            A C++ framework for binary reusable objects, or plugins. It enables exposing and sharing run-time type information for C++ classes
            當然boost中可定可以找到類型代碼的
            應該在type_traits中吧?
            posted on 2010-04-18 18:28 ccsdu2009 閱讀(2069) 評論(6)  編輯 收藏 引用
            Comments
            • # re: Loki技法5-TypeMap
              luoweisong
              Posted @ 2010-04-19 10:58
              很想認真看你的文章,但你的頁面顏色大讓人不舒服了  回復  更多評論   
            • # re: Loki技法5-TypeMap
              空明流轉
              Posted @ 2010-04-19 11:49
              traits類似于不動點,模板類似于lambda算子。整個metaprogramming體系就是一個template functional language。

              boost.mpl+traits才是正道。  回復  更多評論   
            • # re: Loki技法5-TypeMap
              ccsdu2009
              Posted @ 2010-04-19 11:58
              @luoweisong
              我不太懂如何配置顏色
              有空你可以教教我如何設置
                回復  更多評論   
            • # re: Loki技法5-TypeMap
              ccsdu2009
              Posted @ 2010-04-19 11:59
              @空明流轉
              我現在已經不大使用boost了
              這個東西大的出奇
              (當然我只在底層使用若干子庫)  回復  更多評論   
            • # re: Loki技法5-TypeMap
              空明流轉
              Posted @ 2010-04-19 12:40
              我是說在methodology上。
              至于大不大,我覺得至少boost比loki好,后者幾乎是一個實驗性質的東西。  回復  更多評論   
            • # re: Loki技法5-TypeMap
              空明流轉
              Posted @ 2010-04-19 12:43
              還有,你換一個template吧。你這個template的顏色實在難看的不行。  回復  更多評論   
             
            久久天天婷婷五月俺也去| 久久免费视频网站| 国产免费久久久久久无码| 久久精品国产第一区二区三区| 久久久久久久久久久精品尤物 | 亚洲欧美另类日本久久国产真实乱对白 | 777午夜精品久久av蜜臀| 亚洲欧美一级久久精品| 热久久最新网站获取| 少妇人妻综合久久中文字幕| 久久婷婷五月综合97色直播| 国产成人综合久久精品红| 久久婷婷人人澡人人爽人人爱| 久久人人爽人人爽人人片AV高清| 久久久久亚洲av成人网人人软件| 无码国内精品久久人妻| 日韩精品久久无码人妻中文字幕 | 精品人妻伦九区久久AAA片69| 久久综合狠狠色综合伊人| 久久九九青青国产精品| 国产农村妇女毛片精品久久| 久久男人AV资源网站| 精品伊人久久大线蕉色首页| 97久久精品无码一区二区| 777久久精品一区二区三区无码| 久久99国产精品成人欧美| 99久久国产亚洲综合精品| 国产高潮国产高潮久久久| 狠狠色综合久久久久尤物| 久久笫一福利免费导航| 1000部精品久久久久久久久| 一级做a爰片久久毛片看看| 精品久久久久久久久午夜福利 | 美女久久久久久| 亚洲精品乱码久久久久久按摩 | 久久亚洲精品无码VA大香大香| 亚洲国产精品无码久久久蜜芽| 久久国产亚洲精品麻豆| 久久人人爽人人爽人人片av麻烦| 91精品国产高清久久久久久91| 久久婷婷五月综合国产尤物app|