Advertisement
zhangsongcui

Functor(fixed)

Nov 8th, 2011
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.68 KB | None | 0 0
  1. #include <type_traits>
  2. #include <cassert>
  3. #include <functional>
  4.  
  5. template <typename Type, typename Res, typename Enable = void>
  6. struct Functor;
  7.  
  8. template <typename ClassType, typename Res>
  9. struct Functor<ClassType, Res, typename std::enable_if<std::is_class<ClassType>::value>::type> {
  10.     Functor(ClassType* _c, Res (ClassType::* _fn)()): c(_c), fn(_fn) {}
  11.  
  12.     ClassType* c;
  13.     Res (ClassType::*fn)();
  14.  
  15.     template <typename CT2, typename R2>
  16.     bool operator ==(const Functor<CT2, R2>&) const {
  17.         return false;
  18.     }
  19.  
  20.     template <typename CT2>
  21.     typename std::enable_if<std::is_base_of<ClassType, CT2>::value || std::is_base_of<CT2, ClassType>::value, bool>::type
  22.         operator ==(const Functor<CT2, Res>& rhs) const {
  23.             return rhs.c == this->c && rhs.fn == this->fn;
  24.     }
  25.  
  26.     template <typename CT2, typename R2>
  27.     bool operator !=(const Functor<CT2, R2>& rhs) const {
  28.         return !(*this == rhs);
  29.     }
  30. };
  31.  
  32. template <typename FuncType, typename Res>
  33. struct Functor<FuncType, Res, typename std::enable_if<std::is_function<FuncType>::value>::type> {
  34.     Functor(FuncType* _f): f(_f) {}
  35.  
  36.     template <typename FT2, typename R2>
  37.     bool operator ==(const Functor<FT2, R2>&) const {
  38.         return false;
  39.     }
  40.  
  41.     bool operator ==(const Functor<FuncType, Res>& rhs) const {
  42.         return this->f == rhs.f;
  43.     }
  44.  
  45.     template <typename FT2, typename R2>
  46.     bool operator !=(const Functor<FT2, R2>& rhs) const {
  47.         return !(*this == rhs);
  48.     }
  49.  
  50.     FuncType* f;
  51. };
  52.  
  53. template <typename ClassType, typename Res>
  54. Functor<ClassType, Res> functor(ClassType* _c, Res (ClassType::*_fn)()) {
  55.     return Functor<ClassType, Res>(_c, _fn);
  56. }
  57.  
  58. template <typename Res>
  59. Functor<Res (), Res> functor(Res func()) {
  60.     return Functor<Res (), Res>(func);
  61. }
  62.  
  63. struct Base1 {
  64.     virtual void fn1() {}
  65. };
  66.  
  67. struct Base2 {
  68.     virtual void fn2() {}
  69. };
  70.  
  71. struct C {
  72.     virtual void fn3() {}
  73.     virtual int  fn5() { return 0; }
  74. };
  75.  
  76. struct Derive: Base1, Base2 {
  77.     virtual void fn4() {}
  78. };
  79.  
  80. void fn6() {}
  81. void fn7() {}
  82. int  fn8() { return 0; }
  83.  
  84. int main()
  85. {
  86.     // Unit Test
  87.     Derive d;
  88.     auto f1 = functor<Base2>(&d, &Derive::fn2); //说是无法推导ClassType的类型囧
  89.     assert(f1 == f1);
  90.     auto f2 = functor(static_cast<Base2 *>(&d), &Base2::fn2);
  91.     assert(f1 == f2);
  92.     auto f3 = functor(static_cast<Base1 *>(&d), &Derive::fn1);
  93.     assert(f1 != f3);
  94.     auto f4 = functor(&d, &Derive::fn4);
  95.     assert(f1 != f4);
  96.  
  97.     Base2 b2;
  98.     auto f5 = functor(&b2, &Base2::fn2);
  99.     assert(f1 != f5);
  100.  
  101.     C c;
  102.     auto f6 = functor(&c, &C::fn3);
  103.     assert(f1 != f6);
  104.     auto f7 = functor(&c, &C::fn5);
  105.     assert(f6 != f7);
  106.  
  107.     auto f8 = functor(::fn6);
  108.     auto f9 = functor(::fn7);
  109.     auto f10 = functor(::fn8);
  110.     assert(f8 == f8);
  111.     assert(f8 != f9);
  112.     assert(f8 != f10);
  113.     assert(f1 != f9);
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement