实现C++双分派(转)

https://blog.csdn.net/xiaodan007/article/details/24340983

[cpp] view plain copy
 
  1. /******************************************************************** 
  2.  author  :   Clark/陈泽丹 
  3.  created :   2014-4-22 
  4.  purpose :   双分派文件 
  5.     本想用暴力模板双分派解决就好了,因为类型不过五六个,但每每动笔时就有一个 
  6.     幽灵般的声音在回荡:暴力法的遍历开销XXX... 这个声音谁发的?呃,你懂的。  
  7.     纠结一会后决定还是费力点用map表解决算了,毕竟这是服务器,能省开销就省些吧。 
  8.     其实就这种查多删少的操作,还可以用SortedVector类再进一步压榨性能。 
  9.     但想想哥只是个写脚本的,还是老实点好... 
  10. *********************************************************************/  
  11. #pragma once  
  12. #include <map>  
  13. #include <algorithm>  
  14.   
  15. using namespace std;  
  16.   
  17.   
  18.   
  19.   
  20.   
  21.   
  22. templateclass _SIGN, class _BL, class _BR >  
  23. class CommonDispatcher  
  24. {  
  25. public:  
  26.     virtual ~CommonDispatcher()  
  27.     {  
  28.         auto Clear = []( pair<KEY_TYPE const, FunImpl*> _item ) -> void  
  29.         {  
  30.             if( NULL != _item.second )  
  31.             {  
  32.                 delete _item.second;  
  33.                 _item.second = NULL;  
  34.             }  
  35.         };  
  36.         for_each( m_dispatch_map.begin(), m_dispatch_map.end(), Clear );  
  37.         m_dispatch_map.clear();  
  38.     }  
  39.   
  40.     //注册功能  
  41.     templateint _L, int _R, class _Fun >  
  42.     void Regist( const _Fun& _fun )  
  43.     {  
  44.         class Adapter: public FunImpl  
  45.         {  
  46.         public:  
  47.             Adapter(const _Fun& _fun):fun(_fun){}  
  48.             virtual void operator()( _BL *_pl, _BR *_pr )  
  49.             {  
  50.                 fun( _pl, _pr );  
  51.             }  
  52.         private:  
  53.             _Fun fun;  
  54.         };  
  55.         KEY_TYPE key = make_pair(_L,_R);  
  56.         m_dispatch_map[key] = new Adapter(_fun);  
  57.     }  
  58.   
  59.     //派发  
  60.     void operator()( _BL *_pl, _BR *_pr )  
  61.     {  
  62.         if( NULL != _pl && NULL != _pr )  
  63.         {  
  64.             KEY_TYPE key = make_pair(_pl->GetType(),_pr->GetType());  
  65.             auto it = m_dispatch_map.find( key );  
  66.             if( m_dispatch_map.end() != it )  
  67.             {  
  68.                 int k = 0;  
  69.                 (*(it->second))(_pl,_pr);  
  70.             }  
  71.         }  
  72.     }  
  73.   
  74. private:  
  75.     struct FunImpl  
  76.     {  
  77.         virtual void operator()( _BL *_pl, _BR *_pr ) = NULL;  
  78.     };  
  79.     typedef pair<long,long> KEY_TYPE;  
  80.     map< KEY_TYPE, FunImpl* > m_dispatch_map;  
  81. };  

 

 

[cpp] view plain copy
 
  1. struct BaseMoveRune{};  
  2. struct BaseL  
  3. {  
  4.     virtual long GetType(){ return 2; }  
  5. };  
  6. struct BaseR  
  7. {  
  8.     virtual long GetType(){ return 2; }  
  9. };  
  10. struct Test  
  11. {  
  12.     void operator()( BaseL* _pl, BaseR *_pr )  
  13.     {  
  14.         int k = 0;  
  15.     }  
  16. };  

[cpp] view plain copy
 
  1. CommonDispatcher< BaseMoveRune, BaseL, BaseR >  m_dispatcher;  
  2. Test test;  
  3. m_dispatcher.Regist<1,2>(test);  
  4.   
  5. BaseL l;  
  6. BaseR r;  
  7. m_dispatcher( &l, &r );  

posted on 2018-06-27 13:45  吃橙子  阅读(185)  评论(0编辑  收藏  举报

导航