日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

c++ Factor泛型编程示例

發布時間:2023/11/28 生活经验 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ Factor泛型编程示例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

c++ Factor泛型編程示例

c++ 泛型編程 之Factor (c++ 設計新思維)
一.概述
泛化仿函數是將“請求(函數)封裝起來”,存儲與對象中,該對象是具有“value語義”的,因此支持拷貝,賦值和作為函數參數來傳值(pass by value)。通過該對象可間接的處理封裝的請求,類似于boost 中的function功能。本實現采用的是《Modern C++ Design》中的方案。更詳盡的說,具有以下特點:

  1. 可封裝任何處理請求,可接受函數指針,成員函數指針,仿函數,甚至其它泛化仿函數。
  2. 具備型別安全性,不會將錯誤的型別匹配到錯誤的函數上。
  3. 一種帶有“value語義的對象”。
    先介紹下C++中的可調用體:
  4. C風格的函數(C like function): void fun();
  5. C風格的函數指針(C like pointto function): void (*pFun)();
  6. 函數引用(reference to function),其行為本質上和const pointer to function類似。
  7. 仿函數(functor),類中自定義了operator () 的對象。
  8. Operator.*和operator->*的施行結果
  9. 構造函數
    在上述的任一項,可以在右側添加一對圓括號(),在里頭放入一組合適的參數。
    先來討論這樣一個問題,既然想把函數請求封裝到對象中,函數的參數如何確定?這里使用typelist(這是一個型別集,包含型別列表)。這里就可以把typelist作為HTFunctor的一個模板參數,包含所要封裝函數的參數型別信息。下面就先介紹下typelist實作。
    二.HTTypeList
    [cpp]
  10. template <class T, class U>
  11. struct HTTypeList
  12. {
  13.  typedef T Head;  
    
  14.  typedef U Tail;  
    
  15. };
    這是typelist的基本實作(只需兩個類型),現在問題是如何把n個類型連成鏈表。看下面這個例子就明白了
  16. typedef HTTypeList<char, HTTypeList<int, int> >
    (利用模板參數推導,編譯器自動產生,而不是運行期哦),這樣兩個以上的參數都解決了。
    現在問題如何定義一個參數的typelist。方法是,第二個模板參數設為NullType(空類型),這樣每個typelist都以NullType結尾,相當于C字符串的\0功能。看NullType的實作:
    [cpp]
  17. class HTNullType {};
    接著就要生產typelist了(一個參數,兩個參數,三個參數……)。這里用到宏,暫且定義4個typelist。
    [cpp]
  18. #define TYPELIST_1(T1) UTIL::HTTypeList<T1, UTIL::HTNullType>
  19. #define TYPELIST_2(T1, T2) UTIL::HTTypeList<T1, TYPELIST_1(T2) >
  20. #define TYPELIST_3(T1, T2, T3) UTIL::HTTypeList<T1, TYPELIST_2(T2, T3) >
  21. #define TYPELIST_4(T1, T2, T3, T4) UTIL::HTTypeList<T1, TYPELIST_3(T2, T3, T4) >
    另外要解決的問題,函數參數該是值類型(內部內型),還是引用類型(對于對象)。選擇合適的類型顯然能提高程序速度,肯定不想傳遞大對象參數時要額外拷貝。接下來這個東西就要登場了——( HTTypeTraits )
    三:HTTypeTraits
    可用于“編譯期根據型別作判斷”的泛型技術。大家也可參看boost中的type traits。
    [cpp]
  22. // 判斷T及U是否標示同一個類型
  23. template <typename T, typename U>
  24. struct HTIsSameType
  25. {
  26. private:
  27.  template<typename>  
    
  28.  struct In   
    
  29.  { enum { value = false }; };  
    
  30. template<>  
    
  31. struct In<T>  
    
  32. { enum { value = true };  };  
    
  33. public:
  34. enum { value = In<U>::value };  
    
  35. };
    [cpp]
  36. // 依flag選擇兩個類型中的一個,true為T,false為U
  37. template <bool flag, typename T, typename U>
  38. struct HTSelect
  39. {
  40. private:
  41.  template<bool>  
    
  42.  struct In   
    
  43.  { typedef T Result; };  
    
  44. template<>  
    
  45. struct In<false>  
    
  46. { typedef U Result; };  
    
  47. public:
  48. typedef typename In<flag>::Result Result;  
    
  49. };
    [cpp]
  50. // 編譯期bool型
  51. typedef char HTYes;
  52. struct HTNo { char padding[8]; };
  53. // 型別映射為型別,用于模板函數的偏特化,C++標準模板函數不能偏特化
  54. template
  55. struct HTType2Type { typedef T Type; };
  56. // 判斷T是否為類
  57. template
  58. struct HTIsClass
  59. {
  60. // U為類的話,會具現化此重載函數,因為參數為函數指針,即指向成員的函數指針  
    
  61. template <typename U> static HTYes IsClassTest(void(U::*)(void));  
    
  62. // U為非類,會具現化此重載函數  
    
  63. // C++標準:只有當其它所有的重載版本都不能匹配時,具有任意參數列表的重載版本才會被匹配  
    
  64. template <typename U> static HTNo IsClassTest(...);  
    
  65. // 對于sizeof,表達式不會被真正求值,編譯器只推導出表達式的返回結果的型別,因此只需函數的聲明即可  
    
  66. static const bool value = sizeof(IsClassTest<T>(0)) = sizeof(HTYes);  
    
  67. };
  68. // 判斷T是否為引用類型
  69. template
  70. struct HTIsReference
  71. {
  72. template <typename U> static HTYes IsReference(HTType2Type<U&>);  
    
  73. template <typename U> static HTNo IsReference(...);  
    
  74. static const bool value= sizeof(IsReference(HTType2Type<T>())) == sizeof(HTYes);  
    
  75. };
  76. template
  77. class HTTypeTraits
  78. {
  79. public:
  80. enum {   
    
  81.     isVoid =   
    
  82.     HTIsSameType<T, void>::value          ||  
    
  83.     HTIsSameType<T, const void>::value    ||  
    
  84.     HTIsSameType<T, volatile void>::value ||  
    
  85.     HTIsSameType<T, const volatile void>::value  
    
  86. };  
    
  87. enum { isReference = HTIsReference<T>::value };  
    
  88. private:
  89. template<bool IsRef>  
    
  90. struct AdjReference  
    
  91. {  
    
  92.     template<typename U>  
    
  93.     struct In { typedef U const & Result; };  
    
  94. };  
    
  95. template<>  
    
  96. struct AdjReference<true>  
    
  97. {  
    
  98.     template<typename U>  
    
  99.     struct In { typedef U Result; };  
    
  100. };  
    
  101. typedef typename AdjReference<isReference || isVoid>::  
    
  102.     template In<T>::Result AdjType;  
    
  103. // 正確的選擇函數參數的類型  
    
  104. // 對于精巧型(有構造函數和析構函數額外調用)采用引用傳參數,對于純量型(數值型別,枚舉型別,指針,指向成員的指針)采用直接傳值  
    
  105. typedef typename HTSelect<HTIsClass<T>::value, AdjType, T>::Result ParmType;  
    
  106. };
    四:HTFunctor
    HTTypeList及HTTypeTraits提供我們強大的功能。這讓我們實作HTFunctor更加的方便。下面直接看代碼。
    [cpp]
  107. // Functor對象明顯是個小對象,這里采用小對象分配器
  108. // 使用了Command模式及IMPL模式
  109. template
  110. struct HTFunctorImplBase : public HTSmallObject<>
  111. {
  112.  typedef R   ResultType;  
    
  113.  typedef HTEmptyType Parm1;  
    
  114.  typedef HTEmptyType Parm2;  
    
  115. };
  116. template <typename R, class TList, class ObjClass>
  117. struct HTFunctorImpl;
  118. // 無參數版本
  119. template <typename R, class ObjClass>
  120. struct HTFunctorImpl<R, HTNullType, ObjClass> : public HTFunctorImplBase
  121. {
  122. typedef R       ResultType;  
    
  123. virtual ResultType operator()(ObjClass* pObj) = 0;  
    
  124. virtual HTFunctorImpl* Clone() const = 0;  
    
  125. virtual ~HTFunctorImpl() {}  
    
  126. };
  127. // 一個參數版本
  128. template <typename R, typename P1, class ObjClass>
  129. struct HTFunctorImpl<R, TYPELIST_1(P1), ObjClass> : public HTFunctorImplBase
  130. {
  131. typedef R       ResultType;  
    
  132. typedef typename HTTypeTraits<P1>::ParmType   Parm1;  
    
  133. virtual ResultType operator()(Parm1, ObjClass* pObj) = 0;  
    
  134. virtual HTFunctorImpl* Clone() const = 0;  
    
  135. virtual ~HTFunctorImpl() {}  
    
  136. };
  137. // 兩個參數版本
  138. template <typename R, typename P1, typename P2, class ObjClass>
  139. struct HTFunctorImpl<R, TYPELIST_2(P1, P2), ObjClass> : public HTFunctorImplBase
  140. {
  141. typedef R       ResultType;  
    
  142. typedef typename HTTypeTraits<P1>::ParmType   Parm1;  
    
  143. typedef typename HTTypeTraits<P2>::ParmType Parm2;  
    
  144. virtual ResultType operator()(Parm1, Parm2, ObjClass* pObj) = 0;  
    
  145. virtual HTFunctorImpl* Clone() const = 0;  
    
  146. virtual ~HTFunctorImpl() {}  
    
  147. };
  148. // 可調用體(即封裝的處理函數)為仿函數
  149. template <class ParentFunctor, typename Fun, class ObjClass>
  150. class HTFunctorHandler :
  151. public HTFunctorImpl  
    
  152.             <   
    
  153.             typename ParentFunctor::ResultType,  
    
  154.             typename ParentFunctor::ParmList,  
    
  155.             ObjClass  
    
  156.             >  
    
  157. {
  158. typedef typename ParentFunctor::Impl    Base;  
    
  159. public:
  160. typedef typename Base::ResultType ResultType;  
    
  161. typedef typename Base::Parm1 Parm1;  
    
  162. typedef typename Base::Parm1 Parm2;  
    
  163. HTFunctorHandler(const Fun& fun) : m_fun(fun) {}  
    
  164. HTFunctorHandler* Clone() const { return new HTFunctorHandler(*this); }  
    
  165. ResultType operator()(ObjClass* pObj)   
    
  166. { return m_fun(); }  
    
  167. ResultType operator()(Parm1 p1, ObjClass* pObj)  
    
  168. { return m_fun(p1); }  
    
  169. ResultType operator()(Parm1 p1, Parm2 p2, ObjClass* pObj)  
    
  170. { return m_fun(p1, p2); }  
    
  171. private:
  172. Fun m_fun;  
    
  173. };
  174. // 可調用體(即封裝的處理函數)為類成員函數,調用需傳遞對象指針
  175. template <class ParentFunctor, typename Fun, class ObjClass>
  176. class HTMemFunHandler :
  177. public HTFunctorImpl  
    
  178.             <   
    
  179.             typename ParentFunctor::ResultType,  
    
  180.             typename ParentFunctor::ParmList,  
    
  181.             ObjClass  
    
  182.             >  
    
  183. {
  184. typedef typename ParentFunctor::Impl    Base;  
    
  185. public:
  186. typedef typename Base::ResultType ResultType;  
    
  187. typedef typename Base::Parm1 Parm1;  
    
  188. typedef typename Base::Parm1 Parm2;  
    
  189.    HTMemFunHandler(const Fun& fun) : m_fun(fun) {}  
    
  190.    HTMemFunHandler* Clone() const { return new HTMemFunHandler(*this); }  
    
  191.    ResultType operator()(ObjClass* pObj)   
    
  192.    { return (pObj->*m_fun)(); }  
    
  193.    ResultType operator()(Parm1 p1, ObjClass* pObj)   
    
  194.    { return (pObj->*m_fun)(p1); }  
    
  195.    ResultType operator()(Parm1 p1, Parm2 p2, ObjClass* pObj)  
    
  196.    { return (pObj->*m_fun)(p1, p2); }  
    
  197. private:
  198.    Fun m_fun;  
    
  199. };
  200. // HTFunctor實現體
  201. template <typename R, class TList = YKNullType, class ObjClass = YKEmptyType>
  202. class HTFunctor
  203. {
  204.    typedef HTFunctorImpl<R, TList, ObjClass> Impl;  
    
  205. public:
  206.    typedef R       ResultType;  
    
  207.    typedef TList   ParmList;  
    
  208.    typedef typename Impl::Parm1 Parm1;  
    
  209.    typedef typename Impl::Parm2 Parm2;  
    
  210.    HTFunctor() : m_spImpl() {}  
    
  211.    HTFunctor(const HTFunctor& rhs) : m_spImpl(rhs.m_spImpl->Clone()) {}  
    
  212.    explicit HTFunctor(std::auto_ptr<Impl> spImpl) : m_spImpl(spImpl) {}  
    
  213.    HTFunctor& operator=(const HTFunctor& rhs)  
    
  214.    {  
    
  215.        HTFunctor copy(rhs);  
    
  216.        Impl* p = m_spImpl.release();  
    
  217.        m_spImpl.reset(copy.m_spImpl.release());  
    
  218.        copy.m_spImpl.reset(p);  
    
  219.        return *this;  
    
  220.    }  
    
  221.    template <typename Fun>  
    
  222.    HTFunctor(Fun fun)  
    
  223.        : m_spImpl(new   
    
  224.        HTSelect<  
    
  225.            HTIsSameType<ObjClass, HTEmptyType>::value,   
    
  226.            HTFunctorHandler<HTFunctor, Fun, ObjClass>,   
    
  227.            HTMemFunHandler<HTFunctor, Fun, ObjClass> >::Result(fun))  
    
  228.    {}  
    
  229.    ResultType operator()(ObjClass* pObj = HT_NULL) {  
    
  230.        return (*m_spImpl)(pObj);  
    
  231.    }  
    
  232.    ResultType operator()(Parm1 p1, ObjClass* pObj = HT_NULL) {  
    
  233.        return (*m_spImpl)(p1, pObj);  
    
  234.    }  
    
  235.    ResultType operator()(Parm1 p1, Parm2 p2, ObjClass* pObj = HT_NULL) {  
    
  236.        return (*m_spImpl)(p1, p2, pObj);  
    
  237.    }  
    
  238. private:
  239.    std::auto_ptr<Impl> m_spImpl;  
    
  240. };
    五.Krypton Factor C++
    #include
    #include
    #include
    #include
    using namespace std;
    int cnt;
    int n,L;
    int ans;
    int S[100001];
    int dfs(int cur)
    {
    if(cnt++n){
    for(int i=0;i<cur;i++){if(i%4
    0&&i&&i<cur&&i%64!=0)cout<<" “;if(i&&i%64==0&&i<cur)cout<<endl;printf(”%c",‘A’+S[i]);ans++;}
    printf("\n");
    return 0;
    }
    for(int i=0;i<L;i++)
    {
    S[cur]=i;
    int ok=1;
    for(int j=1;j*2<=cur+1;j++)
    {
    int equal_=1;
    for(int k=0;k<j;k++)
    if(S[cur-k]!=S[cur-k-j]){equal_=0;break;}
    if(equal_){ok=0;break;}
    }
    if(ok)if(!dfs(cur+1))return 0;
    }
    return 1;
    }
    int main()
    {
    while(cin>>n>>L&&n&&L){
    ans=0;
    cnt=0;
    dfs(0);
    cout<<ans<<endl;
    }
    return 0;
    }
    六.C++泛型編程與設計模式( 函數內部類 )

class Interface {
virtual void func() =0;
};

template<class T, class P>
Interface *makeAdapter(T tt, P pp) {
int a = 10;
static int count = 10;
class Local : public Interface {
public:
Local(const T &t, const P &p) : p§, t(t) {
// cout << a << endl;
cout << count << endl;
}
virtual void func() {
}
private:
P p;
T t;
static int k;
};
return new Local(tt,pp);
};
這個例子很簡單,開始定義了一個接口,然后定義了一個方法,該方法返回一個Interface的指針,在makeAdapter方法中,定義了Local類,然后繼承自接口Interface,因為這里的Local是個類,是個局部的,所以無法被外部代碼所使用,這就說明了,局部類的使用限制性還是挺大的:

  1. 要么就在方法內部使用。
  2. 如果要在外部使用,不論是直接返回,還是存在其它的包裹方式,都必須繼承已經存在的接口或者是基類。

局部類這種獨特的特性,非常類似于其他語言中的final類,如說PHP,JAVA,因為他是局部的,所以無法被外部繼承。如果不希望類被繼承的話,局部類是個不錯的方法。

參考鏈接:
https://blog.csdn.net/zhuyingqingfen/article/details/10124527
https://blog.csdn.net/Zero_979/article/details/81205702
https://blog.csdn.net/oKanJianLiao/article/details/80711167

總結

以上是生活随笔為你收集整理的c++ Factor泛型编程示例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。